From dcdd2bab4da6d094463fe44c467dc7baf1355322 Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Wed, 18 Dec 2024 09:44:47 +0000 Subject: [PATCH] Some 2024 day 18 tidy-ups. --- bin/day2418.ml | 55 ++++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/bin/day2418.ml b/bin/day2418.ml index b01f462..460efd0 100644 --- a/bin/day2418.ml +++ b/bin/day2418.ml @@ -1,11 +1,13 @@ +(** [pairs_of_ints lst] returns a pair from a list of two elements. *) let pairs_of_ints = function | [ h; h' ] -> (h, h') | _ -> raise (Invalid_argument "pairs_of_ints") +(** [pairs_of_file fname] returns a list of pairs from [fname]. *) let pairs_of_file fname = Aoc.strings_of_file fname |> 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. @@ -50,11 +52,12 @@ let grid_get_by_pos grid p = let idx = grid_idx_by_pos grid p in 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 rec impl = function - | [] -> grid - | p :: t -> + let rec impl rocks = + match Seq.uncons rocks with + | None -> grid + | Some (p, t) -> grid_set_by_pos grid p true; impl t in @@ -74,42 +77,32 @@ let visit grid has_visited cost state = (cost + 1, (x, y - 1)); ] -let check_end dest state = dest = state let width = 71 -let part1 lst = - let count = 1024 in - let grid = - List.to_seq lst |> Seq.take count |> List.of_seq |> make_grid width - in +let common count rocks = + let grid = rocks |> Seq.take count |> grid_of_rocks 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 -> failwith "dijkstra" + dijkstra (visit grid has_visited) + (( = ) (width - 1, width - 1)) + [ (0, (0, 0)) ] + +let part1 count rocks = + match common count rocks with + | None -> failwith "part1" | Some (cost, _) -> cost -let part2 lst = +let part2 start_count rocks = let rec impl count = - 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 - 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) + match common count rocks with None -> count | Some _ -> impl (count + 1) 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 = Printf.sprintf "%d,%d" (idx mod width) (idx / width) let _ = 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) ]