Some 2024 day 18 tidy-ups.

This commit is contained in:
2024-12-18 09:44:47 +00:00
parent 530069a350
commit dcdd2bab4d

View File

@@ -1,11 +1,13 @@
(** [pairs_of_ints lst] returns a pair from a list of two elements. *)
let pairs_of_ints = function let pairs_of_ints = function
| [ h; h' ] -> (h, h') | [ h; h' ] -> (h, h')
| _ -> raise (Invalid_argument "pairs_of_ints") | _ -> raise (Invalid_argument "pairs_of_ints")
(** [pairs_of_file fname] returns a list of pairs from [fname]. *)
let pairs_of_file fname = let pairs_of_file fname =
Aoc.strings_of_file fname Aoc.strings_of_file fname
|> List.map (Aoc.ints_of_string ~sep:",") |> List.map (Aoc.ints_of_string ~sep:",")
|> List.map pairs_of_ints |> List.map pairs_of_ints |> List.to_seq
(** [dijkstra visit check_end states] executes Dijkstra's algorithm. (** [dijkstra visit check_end states] executes Dijkstra's algorithm.
@@ -50,11 +52,12 @@ let grid_get_by_pos grid p =
let idx = grid_idx_by_pos grid p in let idx = grid_idx_by_pos grid p in
grid.grid.(idx) grid.grid.(idx)
let make_grid width rocks = let grid_of_rocks width rocks =
let grid = { grid = Array.make (width * width) false; width } in let grid = { grid = Array.make (width * width) false; width } in
let rec impl = function let rec impl rocks =
| [] -> grid match Seq.uncons rocks with
| p :: t -> | None -> grid
| Some (p, t) ->
grid_set_by_pos grid p true; grid_set_by_pos grid p true;
impl t impl t
in in
@@ -74,42 +77,32 @@ let visit grid has_visited cost state =
(cost + 1, (x, y - 1)); (cost + 1, (x, y - 1));
] ]
let check_end dest state = dest = state
let width = 71 let width = 71
let part1 lst = let common count rocks =
let count = 1024 in let grid = rocks |> Seq.take count |> grid_of_rocks width in
let grid =
List.to_seq lst |> Seq.take count |> List.of_seq |> make_grid width
in
let has_visited = Array.make (width * width) false in let has_visited = Array.make (width * width) false in
match dijkstra (visit grid has_visited)
dijkstra (visit grid has_visited) (( = ) (width - 1, width - 1))
(check_end (width - 1, width - 1)) [ (0, (0, 0)) ]
[ (0, (0, 0)) ]
with let part1 count rocks =
| None -> failwith "dijkstra" match common count rocks with
| None -> failwith "part1"
| Some (cost, _) -> cost | Some (cost, _) -> cost
let part2 lst = let part2 start_count rocks =
let rec impl count = let rec impl count =
let grid = match common count rocks with None -> count | Some _ -> impl (count + 1)
List.to_seq lst |> Seq.take count |> List.of_seq |> make_grid width
in
let has_visited = Array.make (width * width) false in
match
dijkstra (visit grid has_visited)
(check_end (width - 1, width - 1))
[ (0, (0, 0)) ]
with
| None -> grid_idx_by_pos grid (List.nth lst (count - 1))
| Some _ -> impl (count + 1)
in in
impl 1024 let count = impl start_count in
match Seq.uncons (Seq.drop (count - 1) rocks) with
| None -> failwith "part2"
| Some ((x, y), _) -> x + (y * width)
let string_of_idx width idx = let string_of_idx width idx =
Printf.sprintf "%d,%d" (idx mod width) (idx / width) Printf.sprintf "%d,%d" (idx mod width) (idx / width)
let _ = let _ =
Aoc.main pairs_of_file Aoc.main pairs_of_file
[ (string_of_int, part1); (string_of_idx width, part2) ] [ (string_of_int, part1 1024); (string_of_idx width, part2 1024) ]