aboutsummaryrefslogtreecommitdiff
path: root/aoc2023/src/day10
diff options
context:
space:
mode:
Diffstat (limited to 'aoc2023/src/day10')
-rw-r--r--aoc2023/src/day10/.gitignore1
-rw-r--r--aoc2023/src/day10/solve.gleam177
2 files changed, 0 insertions, 178 deletions
diff --git a/aoc2023/src/day10/.gitignore b/aoc2023/src/day10/.gitignore
deleted file mode 100644
index ae40cea..0000000
--- a/aoc2023/src/day10/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-input.txt \ No newline at end of file
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
- }
-}