Compare commits

...

2 Commits

Author SHA1 Message Date
ryan
8562bc8385 finished day 12, thx dijkstra !! 2023-10-23 19:49:18 -05:00
ryan
887d961d29 flatten array of array in grid implementation
makes the new find function much simpler to implement
2023-10-22 11:43:27 -05:00
5 changed files with 172 additions and 15 deletions

View File

@ -1 +1,2 @@
#install_printer Aoc.Vec2.pp;;
#install_printer Aoc.Vec2.pp_grid;;

41
inputs/day12.tt Normal file
View File

@ -0,0 +1,41 @@
abcccccccccccccccccccccccccccccccccccccccccccccccccccaaaaacccccccccccccaaaaaaaccccccccccccccccaaaaaaccccccccccccccccccccccccccaaaaacccaaaccccccccccccccccccccccccccccccaaaaa
abcccccccccaaaccccccccccccaaaccccccccccccccccccccccccaaaaaacccccccccccccaaaaaaaaaaaccaaaaccccaaaaaaacccccccccccccccccccccccccccaaaaaacaaaaccccccccccccccccccccccccccccccaaaa
abcccccccccaaaaaacccccccccaaaacccccccccccccccccccccccaaaaaaccccccccccccaaaaaaaaaaaccaaaaacccaaaaaacccccccccaaacccccccccccccccaaaaaaaacaaaaccccccccccccccccacccccccccccccaaaa
abcccccccccaaaaaacccccccccaaaaccccaacccccccccccccccccaaaaaaccccccccccaaaaaaaaaaaaaacaaaaaaccaacaaaccaacccaaaaaaccccccccccccccaaaaaaaacaaaccccccccccaccccaaaccccccccccccaaaaa
abcccccccaaaaaaaccccccccccaaaacccaaaaccccccccccccaaccccaaacccccccaaacaaaaaaaaaccccccaaaaaacccccaaaccaacccaaaaaacccccccccccccccccaaccccccccccccccccaaacccaaaccccccccccccaaaca
abcccccccaaaaaaacccccccaaacccccccaaaacccccccaaccaaaccccccccccccaaaaacaaaaaaaaaccccccaaaaaccccccccaaaaaaaacaaaaaccaacaaccccccccccaaccccccccccccccccaaaaaaaaaccccccccccccccccc
abcccccccccaaaaaaccaaccaaacccccccaaaacccccccaaaaaaaccccccccccccaaaaaaccccaaaaaacccccccaaaccccccccaaaaaaaaaaaaacccaaaaacccccccaaaccccccccccccccccccaaaaaaaackcccccccccccccccc
abcccccccccaaaaaaccaaaaaaaccccccccccccccccccaaaaaacccccccccccccaaaaaaccccaaaaaaccccccccccccccccccccaaaaccaaaaaccccaaaaaccccccaaaaaccccaaaaaccccccccaaaajjkkkkkccccccaacccccc
abcccccccccaaccccccaaaaaaccccccccccccccccccccaaaaaaaaccccccccccaaaaacccaaaacaaccccccccccccccccccccaaaaaccccccccccaaaaaacccccaaaaaaccccaaaaaccciijjjjjjjjjkkkkkkccaaaaaaccccc
abcaaaccccccccccccccaaaaaaaaccccccccccccccccaaaaaaaaacccccccccccaaaacccaaaccaaccccccccccccccccccccaacaaacccccccccaaaacccccccaaaaaacccaaaaaaciiiijjjjjjjjjoopkkkkcaaaaacccccc
abaaaacccccccccccccaaaaaaaaaccccccccccccccccaaaaaaaacccccccccccccccccccaaaaaaaccccaccaccccccccccccacccaacccccccccccaaccccccccaaaaacccaaaaaaiiiiiijjjjjjoooppppkkcaaaaaaacccc
abaaaaaccccccccccccaaaaaaaaccccccccccccccccaaaaaaaccccccccccccccccccccccaaaaaaccccaaaacccccccccccccccccccccccccccccccccccccccaaaaccccaaaaaiiiinnnoooooooooppppkkkaaaaaaacccc
abaaaaacccccccccccaaaaaaaccccccccccccccccccccccaaacccccccccccccccccccaaaaaaaacccccaaaaccccccccccccaaccaacccccaccccacccccccccccccccccccaaaciiinnnnoooooooouupppkkkaaaaaaacccc
abaaaaccccccccccccccccaaaccccccccccccccccccccccaaacccccccaaccccccccccaaaaaaaaacccaaaaaacccccccccccaaaaaaccccaaaaaaaacccccccccccccaaccccccciiinnnntttooouuuuupppiiacaaacccccc
abaaaacccccccccccccccccaaccccccccccccccccccccccccccccccaaaacacccccccccaaaaaaaacccaaaaaacccccccccccaaaaaccccccaaaaaacccccccccccaaaaaacccccciinnnttttuuuuuuuuuuppiiccaaacccccc
abcccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaacccccccccccaaaaaaaccccaacccccaaccccccaaaaaacccccaaaaaacccccccccccaaaaaccccccciinnntttttuuuuxyuuuppiiicccccccccc
abccccccccccccccccccccccccccccccccccccaaacccccccaaccccccaaaaccccccccccccaaccccccccccccccccaacaaacaaaaaaaacccaaaaaaaaccccccccccaaaaaaaccccchinnnttxxxxuuxyyyuuppiiiiccccccccc
abccccccccccccccccccccccccccccccccccccaaaaaaccccaaacccccaaaaccccccccccccaaccccccccccccccccaaaaaccaaaaaaaaccaaaaaaaaaaccccccccaaaaaaaaccccchhhnnttxxxxxxxyyuvppppiiiccccccccc
abccccccccccccccccccccccccccccccccccaaaaaaaaaaccaaaaaaacacaacccccccccccccccccaaaccccccccaaaaaaccccccaacccccaaaaaaaaaaccccccccaaaaaaaaccccchhhnntttxxxxxxyyvvvppqqiiicccccccc
abccccccccccccccccccccccccccccaacaccaaaaaaaaaaaaaaaaaaacccccccccccccccccccccaaaaaaccccccaaaaaaacccccaacccccaccaaaaacacccccccccacaaaccccccchhhnnnttxxxxxyyyvvvvqqqqiiiccccccc
SbccccccccccccccccccccccccccccaaaaccaaaaaaacaaaaaaaaaaccccccccccccccccccccccaaaaaaccccccccaaaaaaccccccccccccccaaaaccccccccccccccaaacccccchhhmmmtttxxxEzzyyyyvvvqqqqiiccccccc
abcccccccccccccccccccccccccccaaaaaccccaaaaaccaaaaaaaaacccccccccccccccaaaaaccaaaaaaccccccccaaccaacccccccccccccccaacccccccaaaaccccccccccccchhhmmmtttxxxyyyyyyyyvvvqqqjjjcccccc
abcccaaacccccccccccccccccccccaaaaaacccaacaaaaaaaaaaaaacccccccccccccccaaaaacccaaaaaccccccccaacccccccccccccccccccccccccccaaaaacccccccccccchhhmmmttsxxyyyyyyyyvvvvvqqqjjjcccccc
abcccaaaaaacccaacaaccccccccccacaaaacccaacccaaaaaaaaaaaacccccccccccccaaaaaacccaacaaccccccccccccccccccccccccccccccccaacccaaaaaaccccccccccchhhmmmssxxwwwwyyywvvvvvqqqjjjjcccccc
abccaaaaaaacccaaaaaccccccccccccaaccccccccccaaaaaaaccaaccccccccccccccaaaaaacccccccccccccccccccccccccccccccccccaaccaaacccaaaaaacccccccaaachhhmmssswwwwwwyyywvvqqqqqqjjjccccccc
abcaaaaaaacccccaaaaacccccccccccccccccccccccccccaaaccccccccccccccccccaaaaaacccccccccccaaccccaaccccccccccccccccaaacaaacccaaaaaacccccccaaacgggmmsssswwwswwyywwrrqqqjjjjcccccccc
abcaaaaaaaccccaaaaaacccccccccccccccccccccccaaccaaaccccccccccccccccccccaaccccccccccccaaccccaaaacccccccccccccccaaaaaaccccccaacccccccaacaaagggmmmssssssswwwwwwrrqjjjjjddccccccc
abcccaaaaaacccaaaacccccccccccccccccccccccccaaacaaccccccccccccccccccccccccccccccccaaaaacaacaaaaccccccccccccccccaaaaaaaaccccccccccccaaaaaagggmmmmssssssswwwwrrrkjjjjddddcccccc
abcccaaaaaacccccaaccccccccccccccccccccccccccaaaaaccccccccccccccccccccccccccccccccaaaaaaaacaaaacaaccccccaaccaaaaaaaaaaacccccccccccccaaaaaggggmmmmllllsrrwwwrrkkkjdddddaaacccc
abcccaaaccccccccccccaacccccccccccccccccccccaaaaaaccccccccccccccccccccccccccccccccccaaaaacccccccaaaaaaccaaaaaaaaaaaaaacccccccccccccccaaaaaggggmmllllllrrrrrrrkkkdddddaaaccccc
abccccaaaaaaccccccccaacaaaccccccccacccaaccaaaaaaaaccccccccccaaaccccccaacccccccccccaaaaaccccccccaaaaacccaaaaaaaaaaaaccccccccccccccccaaacaacggggggflllllrrrrrrkkddddaaaaaccccc
abccccaaaaacccccccccaaaaacccccccccaaaaaaccaaaaaaaaccccccccccaaacacccaaaaccccccccccaacaaacccccaaaaaaccccaaaaaaaccaaacccccccccccccccccaacccccggggffffllllrrrrkkkdddaaaaaaacccc
abccaaaaaaacccccccaaaaaaccccccccccaaaaaccccccaacccccaaccccaacaaaaaccaaaacccccccaaccccaaccccccaaaaaaaccaaaaaaaaccaaaccccccccccccccccccaaaccccccgffffflllkkkkkkeedaaaaaaaacccc
abccaaaaaaacccccccaaaaaaacccccccccaaaaaacccccaacccccaaacccaaaaaaaaccaaaacccaaaaacccccccccccccccaaaaaacaaaaaaaacccccccccccccccccccccccaaaacaacccccffffllkkkkkeeedccaaaaaacccc
abccccaaaaaaccccccccaaaaaacccccccaaaaaaaacccccaaccccaaaaaaaaaaaaccccccccccaaaaaaaacccccccccccccaaccaaccccaaaccccccaacccccccccccccccccaaaaaaaccccccfffffkkkkeeeecccaacccccccc
abccccaaccaaccccccccaaccaacccccccaaaaaaaacccccaaccaaaaaaaaccaaaaacccccccccaaaaaaaaccccccccccaacaaccccccccaaccccaacaaaccccaacccccccccccaaaaaaccccccaafffeeeeeeecccccccccccccc
abccccaaccccccccccccaaccccccccccccccaacccccaaaaaaaaaaaaaaacaaacaaaaaaacaccaaaaaaacccccccaaacaacccccccccccccccccaaaaaccccaaaacccccccaaaaaaaaccccccaaaaffeeeeeeeccccccccccccca
abacccccccccccccaaacccccccccccccccccaacccccaaaaaaaaaaaaaacccaaccaaaaaaaaaaaaaccaaacccccccaaaaaccccccccccccccccccaaaaaaccaaaacccccccaaaaaaaaaccccccaaacceeeeeccccccccccccccaa
abaaccccccccccaaaaaacccccccccccccccccccccccccaaaacccaaaaaaccccccaaaaaaaaaaaaaaaaaaaccccccaaaaaaacccaaaccccccccaaaaaaaaccaaaaccccccccaaaaaaaaccccccccccccaaacccccccccccaaacaa
abaaccccccccccaaaaaacccccccccccccccccccccccccaaaaacaaaaaaaccccccaaaaaaaaaaaaaaaaaaccccccaaaaaaaaccccaaaaccccccaaaaacaaccccccccccccccccaaaaaaacccccccccccacacccccccccccaaaaaa
abacccccccccccaaaaaaccccccccccccccccccccccccaaaaaacaaaccaaccccccaaaaaaccaaaaaaaaccccccccaaaaaaaaccaaaaaacccccccccaaaccccccccccccccccccaacccccccccccccccccccccccccccccccaaaaa

87
src/day12.ml Normal file
View File

@ -0,0 +1,87 @@
open Containers
let infinity = 1000000000
type node =
{ char : char
; mutable visited : bool
; mutable distance : int
; mutable previous : (Vec2.t * node) option
}
[@@deriving show]
let parse_grid start_anywhere =
let s = ref @@ Vec2.of_tuple (0, 0) in
let e = ref @@ Vec2.of_tuple (0, 0) in
let unvisited = ref [] in
let grid =
Utils.lines_of_input 12
|> Vec2.parse_grid (fun char ->
{ char; visited = false; distance = infinity; previous = None })
in
Vec2.iter_grid grid (fun pos ->
let n = Vec2.at_e grid pos in
match n.char with
| 'E' -> e := pos
| 'S' ->
n.distance <- 0;
s := pos
| 'a' when start_anywhere ->
n.distance <- 0;
unvisited := pos :: !unvisited
| _ -> ());
grid, !e, !s, !unvisited
;;
let reachable f t =
let height c =
match c with
| 'S' -> 'a'
| 'E' -> 'z'
| c -> c
in
Char.compare (height f) (height t) >= -1
;;
let rec path grid goal current unvisited =
let current_node = Vec2.at_e grid current in
let neighbors = Vec2.directions |> List.map (fun dir -> Vec2.(current + dir)) in
neighbors
|> List.iter (fun neighbor ->
match Vec2.at grid neighbor with
| Some node when (not node.visited) && reachable current_node.char node.char ->
let new_distance = current_node.distance + 1 in
if new_distance < node.distance
then (
node.distance <- new_distance;
node.previous <- Some (current, current_node));
if Option.is_none @@ List.find_opt (fun x -> Vec2.(x = neighbor)) !unvisited
then unvisited := neighbor :: !unvisited
| _ -> ());
current_node.visited <- true;
unvisited
:= List.sort
(fun a b ->
let a = Vec2.at_e grid a in
let b = Vec2.at_e grid b in
a.distance - b.distance)
!unvisited;
match !unvisited with
| shortest :: _ when Vec2.(shortest = goal) -> Vec2.at grid shortest
| shortest :: rest -> path grid goal shortest @@ ref rest
| [] -> None
;;
let%expect_test "Day 12.1" =
let grid, e, s, unvisited = parse_grid false in
let solution = Option.get_exn_or "coulnd't find" @@ path grid e s @@ ref unvisited in
Printf.printf "%d" solution.distance;
[%expect {| 497 |}]
;;
let%expect_test "Day 12.2" =
let grid, e, s, unvisited = parse_grid true in
let solution = Option.get_exn_or "coulnd't find" @@ path grid e s @@ ref unvisited in
Printf.printf "%d" solution.distance;
[%expect {| 492 |}]
;;

View File

@ -1,7 +1,13 @@
open Containers
type t = int * int [@@deriving show]
type 'a grid = 'a array array
type 'a grid =
{ width : int
; height : int
; items : 'a array
}
[@@deriving show]
let up = 0, 1
let down = 0, -1
@ -14,24 +20,44 @@ let ( + ) a b = Pair.map_same2 ( + ) a b
let ( - ) a b = Pair.map_same2 ( - ) a b
let ( = ) a b = Pair.equal ( = ) ( = ) a b
let at grid point =
let x, y = to_tuple point in
let at (grid : 'a grid) (point : t) =
let x, y = point in
if x >= 0 && x < grid.width && y >= 0 && y < grid.height
then Array.get_safe grid.items @@ Int.((grid.width * y) + x)
else None
;;
let at_e (grid : 'a grid) (point : t) =
Option.get_exn_or "out of bounds!" @@ at grid point
;;
let find (grid : 'a grid) pred =
let open Option.Infix in
let* row = Array.get_safe grid y in
Array.get_safe row x
let* idx, item = Array.find_idx pred grid.items in
let y = idx / grid.width in
let x = idx mod grid.width in
Some ((x, y), item)
;;
let parse_grid parse_char lines =
lines
|> Array.of_list
|> Array.map Fun.(String.to_seq %> Seq.map parse_char %> Seq.to_array)
let parse_grid parse_char lines : 'a grid =
match lines with
| first_line :: _ ->
let width = String.length first_line in
let height = List.length lines in
let yeet =
lines
|> List.map String.to_list
|> List.flatten
|> List.map parse_char
|> Array.of_list
in
{ width; height; items = yeet }
| _ -> failwith "somethin fucd up"
;;
let iter_grid grid callback =
let grid_h = Array.length grid in
let grid_w = Array.length grid.(0) in
for y = 0 to Int.(grid_h - 1) do
for x = 0 to Int.(grid_w - 1) do
let iter_grid (grid : 'a grid) callback =
for y = 0 to Int.(grid.height - 1) do
for x = 0 to Int.(grid.width - 1) do
callback (x, y)
done
done

View File

@ -1,5 +1,5 @@
type t [@@deriving show]
type 'a grid
type 'a grid [@@deriving show]
val up : t
val down : t
@ -12,5 +12,7 @@ val ( + ) : t -> t -> t
val ( - ) : t -> t -> t
val ( = ) : t -> t -> bool
val at : 'a grid -> t -> 'a option
val at_e : 'a grid -> t -> 'a
val parse_grid : (char -> 'a) -> string list -> 'a grid
val find : 'a grid -> ('a -> bool) -> (t * 'a) option
val iter_grid : 'a grid -> (t -> unit) -> unit