diff options
author | J.J <thechairman@thechairman.info> | 2024-05-30 21:49:58 -0400 |
---|---|---|
committer | J.J <thechairman@thechairman.info> | 2024-05-30 21:49:58 -0400 |
commit | 231c2b688d1e6cf0846d46e883da30e042a9c6cf (patch) | |
tree | 98a6d3a461fe190b38b2cf33a708a1d01703fa70 /aoc2023-gleam/src/day12/solve.gleam | |
parent | fe088aa5778dcdbaab4dd8d4a7395a91c444b45c (diff) | |
parent | a2c2b728ec6051323ed937f54816089cd2ae9d20 (diff) | |
download | gleam_aoc-231c2b688d1e6cf0846d46e883da30e042a9c6cf.tar.gz gleam_aoc-231c2b688d1e6cf0846d46e883da30e042a9c6cf.zip |
Merge branch 'main' of https://github.com/hunkyjimpjorps/AdventOfCode
Diffstat (limited to 'aoc2023-gleam/src/day12/solve.gleam')
-rw-r--r-- | aoc2023-gleam/src/day12/solve.gleam | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/aoc2023-gleam/src/day12/solve.gleam b/aoc2023-gleam/src/day12/solve.gleam new file mode 100644 index 0000000..893b83c --- /dev/null +++ b/aoc2023-gleam/src/day12/solve.gleam @@ -0,0 +1,90 @@ +import adglent.{First, Second} +import gleam/io +import gleam/string +import gleam/list +import gleam/int +import gleam/result +import utilities/memo.{type Cache} + +type ParserState = + #(String, List(Int), Int, Bool) + +fn parse_folds(input: String, folds: Int) { + let records = string.split(input, "\n") + use record <- list.map(records) + let assert Ok(#(template, sets_str)) = string.split_once(record, " ") + + let template = + template + |> list.repeat(folds) + |> list.intersperse("?") + |> string.concat + let sets = + sets_str + |> string.split(",") + |> list.map(int.parse) + |> result.values + |> list.repeat(folds) + |> list.flatten() + + #(template, sets) +} + +fn do_count( + template: String, + groups: List(Int), + left: Int, + gap: Bool, + cache: Cache(ParserState, Int), +) -> Int { + use <- memo.memoize(cache, #(template, groups, left, gap)) + case template, groups, left, gap { + "", [], 0, _ -> 1 + "?" <> t_rest, [g, ..g_rest], 0, False -> + do_count(t_rest, g_rest, g - 1, g == 1, cache) + + do_count(t_rest, groups, 0, False, cache) + "?" <> t_rest, [], 0, False + | "?" <> t_rest, _, 0, True + | "." <> t_rest, _, 0, _ -> do_count(t_rest, groups, 0, False, cache) + "#" <> t_rest, [g, ..g_rest], 0, False -> + do_count(t_rest, g_rest, g - 1, g == 1, cache) + "?" <> t_rest, gs, l, False | "#" <> t_rest, gs, l, False -> + do_count(t_rest, gs, l - 1, l == 1, cache) + _, _, _, _ -> 0 + } +} + +fn count_solutions(acc: Int, condition: #(String, List(Int))) -> Int { + use cache: Cache(ParserState, Int) <- memo.create() + let #(template, groups) = condition + acc + do_count(template, groups, 0, False, cache) +} + +pub fn part1(input: String) { + input + |> parse_folds(1) + |> list.fold(0, count_solutions) + |> string.inspect +} + +pub fn part2(input: String) { + input + |> parse_folds(5) + |> list.fold(0, count_solutions) + |> string.inspect +} + +pub fn main() { + let assert Ok(part) = adglent.get_part() + let assert Ok(input) = adglent.get_input("12") + case part { + First -> + part1(input) + |> adglent.inspect + |> io.println + Second -> + part2(input) + |> adglent.inspect + |> io.println + } +} |