From 4bc781585148385762d17b5f3e3ba027f7eab061 Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Mon, 16 Dec 2024 13:57:13 +0000 Subject: [PATCH] 6x speed up on 24 day 16 part 2 We filter out already visited states when adding them to the work list. We also don't sort the work list as we're already generating it in a sorted (by cost) order. --- bin/day2416.ml | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/bin/day2416.ml b/bin/day2416.ml index d9c14b6..2e6f7b7 100644 --- a/bin/day2416.ml +++ b/bin/day2416.ml @@ -15,10 +15,7 @@ let rec dijkstra visit check_end states = | (cost, state) :: t -> if check_end state then Some (cost, state, t) else - let new_states = - visit cost state |> List.sort compare_costs - |> List.merge compare_costs t - in + let new_states = visit cost state |> List.merge compare_costs t in dijkstra visit check_end new_states let visited_idx grid ((dx, dy), p) = @@ -45,21 +42,23 @@ let visit grid visited_grid cost state = (cost + 1000, ((dy, -dx), p) :: state); ]) -let visit_max grid visited_grid max_cost cost state = - let has_visited = visited_grid.(visited_idx grid (List.hd state)) < cost in +let has_visited grid visited_grid (cost, state) = + visited_grid.(visited_idx grid (List.hd state)) < cost + +let visit_max grid visited_grid cost state = let (dx, dy), ((x, y) as p) = List.hd state in - if has_visited then [] - else if cost > max_cost then [] + if has_visited grid visited_grid (cost, state) then [] else if Aoc.Grid.get_by_pos grid p = '#' then [] else ( - (*Printf.printf "%d (%d, %d)\n" cost x y; - flush stdout;*) + Printf.printf "%d (%d, %d)\n" cost x y; + flush stdout; visited_grid.(visited_idx grid (List.hd state)) <- cost; [ (cost + 1, ((dx, dy), (x + dx, y + dy)) :: state); (cost + 1000, ((-dy, dx), p) :: state); (cost + 1000, ((dy, -dx), p) :: state); - ]) + ] + |> List.filter (fun x -> not (has_visited grid visited_grid x))) let[@warning "-32"] print_point (x, y) = Printf.printf "(%d, %d)" x y @@ -80,13 +79,10 @@ let part1 (grid, start_pos) = let part2 (grid, start_pos) = let cost = part1 (grid, start_pos) in - let visited_grid = Array.make (Aoc.Grid.length grid * 4) max_int in + let visited_grid = Array.make (Aoc.Grid.length grid * 4) cost in let rec impl acc lst = match - dijkstra - (visit_max grid visited_grid cost) - (check_end2 grid visited_grid) - lst + dijkstra (visit_max grid visited_grid) (check_end2 grid visited_grid) lst with | None -> acc | Some (_, states, remainder) ->