diff options
author | HJ <thechairman@thechairman.info> | 2023-12-03 02:15:48 -0500 |
---|---|---|
committer | HJ <thechairman@thechairman.info> | 2023-12-03 02:15:48 -0500 |
commit | 05f0ca3e2c25fedbb9f924c6b79a839d087e04c8 (patch) | |
tree | 91993a9d5cea7c1c79db9956cb4a938d7c1bcbb0 /aoc2023 | |
parent | 5108ae09e37ff6c71a9d791ef70897c4b6791c42 (diff) | |
download | gleam_aoc-05f0ca3e2c25fedbb9f924c6b79a839d087e04c8.tar.gz gleam_aoc-05f0ca3e2c25fedbb9f924c6b79a839d087e04c8.zip |
day 3 complete
Diffstat (limited to 'aoc2023')
-rw-r--r-- | aoc2023/src/day3/solve.gleam | 63 |
1 files changed, 24 insertions, 39 deletions
diff --git a/aoc2023/src/day3/solve.gleam b/aoc2023/src/day3/solve.gleam index 5df337d..9e0cd0d 100644 --- a/aoc2023/src/day3/solve.gleam +++ b/aoc2023/src/day3/solve.gleam @@ -11,10 +11,14 @@ type Coord { Coord(x: Int, y: Int) } +type PartKind { + Gear + SomethingElse +} + type Symbol { Number(Int) - Gear - OtherSymbol + Part(PartKind) Empty } @@ -25,8 +29,8 @@ fn to_symbol(c: String) -> Symbol { case int.parse(c), c { Ok(n), _ -> Number(n) Error(Nil), "." -> Empty - Error(Nil), "*" -> Gear - _, _ -> OtherSymbol + Error(Nil), "*" -> Part(Gear) + _, _ -> Part(SomethingElse) } } @@ -40,7 +44,7 @@ fn to_board(input: String) -> Board { |> dict.from_list() } -fn find_all_numbers(b: Board) { +fn find_all_parts(b: Board) { b |> dict.filter(fn(_, v) { case v { @@ -90,41 +94,25 @@ fn check_part_neighbors( ) -> Result(Int, Nil) { let #(coords, n) = part - let neighbors = - coords - |> list.flat_map(all_neighbors) - |> list.unique() - - case - list.any( - neighbors, - fn(c) { - let content = dict.get(board, c) - content == Ok(OtherSymbol) || content == Ok(Gear) - }, - ) - { - True -> Ok(n) - False -> Error(Nil) - } + coords + |> list.flat_map(all_neighbors) + |> list.unique() + |> list.map(dict.get(board, _)) + |> result.all() + |> result.replace(n) } pub fn part1(input: String) { let board = to_board(input) board - |> find_all_numbers + |> find_all_parts |> group_parts([]) |> list.map(check_part_neighbors(_, board)) |> result.values |> int.sum } -fn find_gears(b: Board) { - dict.filter(b, fn(_, v) { v == Gear }) - |> dict.keys -} - fn to_part_with_neighbors(part: #(List(Coord), Int)) { let #(coords, n) = part @@ -149,15 +137,11 @@ fn find_parts_near_gear(gear: Coord, parts: List(#(List(Coord), Int))) { } fn keep_gears_near_two_parts(sets_of_parts: List(List(Int))) { - list.filter_map( - sets_of_parts, - fn(ps) { - case ps { - [p1, p2] -> Ok(p1 * p2) - _ -> Error(Nil) - } - }, - ) + use ps <- list.filter_map(sets_of_parts) + case ps { + [p1, p2] -> Ok(p1 * p2) + _ -> Error(Nil) + } } pub fn part2(input: String) { @@ -165,12 +149,13 @@ pub fn part2(input: String) { let parts = board - |> find_all_numbers + |> find_all_parts |> group_parts([]) |> list.map(to_part_with_neighbors) board - |> find_gears + |> dict.filter(fn(_, v) { v == Part(Gear) }) + |> dict.keys |> list.map(find_parts_near_gear(_, parts)) |> keep_gears_near_two_parts |> int.sum |