Some 2024 day 18 tidy-ups.
This commit is contained in:
@@ -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) ]
|
||||||
|
Reference in New Issue
Block a user