From 530069a35057bb583627522cefcaccb6e9f79c44 Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Wed, 18 Dec 2024 09:27:50 +0000 Subject: [PATCH] Day 2024 part 2 --- bin/day2418.ml | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/bin/day2418.ml b/bin/day2418.ml index f21fc5c..b01f462 100644 --- a/bin/day2418.ml +++ b/bin/day2418.ml @@ -26,9 +26,9 @@ let pairs_of_file fname = let rec dijkstra visit check_end = let compare_costs (lhs, _) (rhs, _) = compare lhs rhs in function - | [] -> failwith "dijkstra" + | [] -> None | (cost, state) :: t -> - if check_end state then (cost, state) + if check_end state then Some (cost, state) else let new_states = visit cost state |> List.merge compare_costs t in dijkstra visit check_end new_states @@ -68,26 +68,48 @@ let visit grid has_visited cost state = let x, y = state in has_visited.(grid_idx_by_pos grid state) <- true; [ - (cost + 1, (x - 1, y)); (cost + 1, (x + 1, y)); - (cost + 1, (x, y - 1)); (cost + 1, (x, y + 1)); + (cost + 1, (x - 1, y)); + (cost + 1, (x, y - 1)); ] let check_end dest state = dest = state +let width = 71 let part1 lst = - let width = 71 in let count = 1024 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 cost, _ = + match dijkstra (visit grid has_visited) (check_end (width - 1, width - 1)) [ (0, (0, 0)) ] - in - cost + with + | None -> failwith "dijkstra" + | Some (cost, _) -> cost -let _ = Aoc.main pairs_of_file [ (string_of_int, part1) ] +let part2 lst = + 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) + in + impl 1024 + +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) ]