diff options
Diffstat (limited to 'aoc2023/src/day10/solve.gleam')
-rw-r--r-- | aoc2023/src/day10/solve.gleam | 177 |
1 files changed, 0 insertions, 177 deletions
diff --git a/aoc2023/src/day10/solve.gleam b/aoc2023/src/day10/solve.gleam deleted file mode 100644 index c33634d..0000000 --- a/aoc2023/src/day10/solve.gleam +++ /dev/null @@ -1,177 +0,0 @@ -import adglent.{First, Second} -import gleam/bool -import gleam/dict.{type Dict} -import gleam/list -import gleam/int -import gleam/io -import gleam/set.{type Set} -import gleam/string - -type Posn { - Posn(row: Int, col: Int) -} - -fn add_posns(p1: Posn, p2: Posn) -> Posn { - Posn(p1.row + p2.row, p1.col + p2.col) -} - -type PipeGrid = - Dict(Posn, String) - -const north = Posn(-1, 0) - -const south = Posn(1, 0) - -const east = Posn(0, 1) - -const west = Posn(0, -1) - -const initial_directions = [ - #(north, ["|", "7", "F"]), - #(south, ["|", "J", "L"]), - #(east, ["-", "J", "7"]), - #(west, ["-", "F", "L"]), -] - -fn pipe_neighbors(pipe: String) -> List(Posn) { - case pipe { - "|" -> [north, south] - "-" -> [east, west] - "L" -> [north, east] - "F" -> [south, east] - "7" -> [south, west] - "J" -> [north, west] - _ -> panic as "bad pipe" - } -} - -fn make_grid(input: String) -> PipeGrid { - { - use r, row <- list.index_map(string.split(input, "\n")) - use c, col <- list.index_map(string.to_graphemes(row)) - #(Posn(r, c), col) - } - |> list.flatten - |> dict.from_list -} - -fn valid_start_direction(grid: PipeGrid, s: Posn) { - let assert [dir, ..] = { - use d <- list.filter_map(initial_directions) - let #(delta, valids) = d - let neighbor = add_posns(s, delta) - case dict.get(grid, neighbor) { - Ok(pipe) -> - case list.contains(valids, pipe) { - True -> Ok(neighbor) - False -> Error(Nil) - } - Error(_) -> Error(Nil) - } - } - dir -} - -fn to_next_pipe(current: Posn, grid: PipeGrid, acc: List(Posn)) { - let assert [prev, ..] = acc - let assert Ok(pipe) = dict.get(grid, current) - use <- bool.guard(pipe == "S", [current, ..acc]) - let assert [next] = { - pipe - |> pipe_neighbors - |> list.filter_map(fn(p) { - case add_posns(p, current) { - neighbor if neighbor == prev -> Error(Nil) - neighbor -> Ok(neighbor) - } - }) - } - to_next_pipe(next, grid, [current, ..acc]) -} - -pub fn part1(input: String) { - let grid = - input - |> make_grid - - let assert Ok(s) = - grid - |> dict.filter(fn(_, v) { v == "S" }) - |> dict.keys - |> list.first - - grid - |> valid_start_direction(s) - |> to_next_pipe(grid, [s]) - |> list.length - |> fn(i) { { { i - 1 } / 2 } } - |> string.inspect -} - -fn trace_ray(p: Posn, loop: Set(Posn), grid: PipeGrid) -> Bool { - use <- bool.guard(set.contains(loop, p), False) - int.is_odd(count_crossings(p, loop, grid, 0, "")) -} - -fn count_crossings( - p: Posn, - loop: Set(Posn), - grid: PipeGrid, - acc: Int, - corner: String, -) { - let maybe_cell = dict.get(grid, p) - use <- bool.guard(maybe_cell == Error(Nil), acc) - let assert Ok(cell) = maybe_cell - let next = add_posns(p, east) - case set.contains(loop, p) { - False -> count_crossings(next, loop, grid, acc, corner) - True -> - case corner, cell { - _, "|" -> count_crossings(next, loop, grid, acc + 1, corner) - _, "F" | _, "L" -> count_crossings(next, loop, grid, acc, cell) - "F", "J" | "L", "7" -> count_crossings(next, loop, grid, acc + 1, "") - "F", "7" | "L", "J" -> count_crossings(next, loop, grid, acc, "") - _, _ -> count_crossings(next, loop, grid, acc, corner) - } - } -} - -pub fn part2(input: String) { - let grid = - input - |> make_grid - - let assert Ok(s) = - grid - |> dict.filter(fn(_, v) { v == "S" }) - |> dict.keys - |> list.first - - let loop_pipes = - grid - |> valid_start_direction(s) - |> to_next_pipe(grid, [s]) - |> set.from_list - - grid - |> dict.keys - |> list.filter(trace_ray(_, loop_pipes, grid)) - |> list.length() - |> string.inspect -} - -pub fn main() { - let assert Ok(part) = adglent.get_part() - let assert Ok(input) = adglent.get_input("10") - case part { - First -> - part1(input) - |> adglent.inspect - |> io.println - Second -> - part2(input) - |> adglent.inspect - |> io.println - } -} |