From 70c53d51735feb8b8a4a82aab70d0d85766febbf Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Sun, 15 Dec 2024 08:10:42 +0000 Subject: [PATCH] 2024 day 15 part 1 --- bin/day2415.ml | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ bin/dune | 6 ++-- 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 bin/day2415.ml diff --git a/bin/day2415.ml b/bin/day2415.ml new file mode 100644 index 0000000..98fe22c --- /dev/null +++ b/bin/day2415.ml @@ -0,0 +1,75 @@ +type grid = { grid : char array; width : int; height : int } + +let grid_make strs = + let grid = + List.fold_left String.cat "" strs |> String.to_seq |> Array.of_seq + in + let height = List.length strs in + let width = Array.length grid / height in + { grid; width; height } + +let grid_copy grid = { grid with grid = Array.copy grid.grid } +let grid_height grid = grid.height +let[@warning "-32"] grid_length grid = grid.width * grid.height + +let[@warning "-32"] grid_print grid = + Array.iteri + (fun i c -> + print_char c; + if i mod grid.width = grid.width - 1 then print_newline ()) + grid.grid + +let find_start_idx grid = + match Array.find_index (( = ) '@') grid.grid with + | None -> failwith "find_start_idx" + | Some x -> x + +let instrs_of_file fname = + let strs = Aoc.strings_of_file fname in + let rec impl acc = function + | [] | "" :: [] -> failwith "instrs_of_file.impl" + | "" :: t -> (List.rev acc, t) + | h :: t -> impl (h :: acc) t + in + let grid, moves = impl [] strs in + let grid = grid_make grid in + ( grid, + List.fold_left String.cat "" moves |> String.to_seq |> List.of_seq, + find_start_idx grid ) + +let rec move_robot grid i di = + match grid.grid.(i + di) with + | '#' -> i + | 'O' -> + if move_robot grid (i + di) di = i + di then i else move_robot grid i di + | '.' -> + grid.grid.(i + di) <- grid.grid.(i); + grid.grid.(i) <- '.'; + i + di + | _ -> failwith "move_robot" + +let process_move grid robot dir = + match dir with + | '^' -> move_robot grid robot ~-(grid_height grid) + | 'v' -> move_robot grid robot (grid_height grid) + | '<' -> move_robot grid robot ~-1 + | '>' -> move_robot grid robot 1 + | _ -> failwith "process_move" + +let rec process_moves grid robot = function + | [] -> grid + | h :: t -> process_moves grid (process_move grid robot h) t + +let calc_score grid = + Array.mapi + (fun idx c -> + if c = 'O' then (idx mod grid.width) + (100 * (idx / grid.height)) else 0) + grid.grid + |> Array.fold_left ( + ) 0 + +let part (grid, moves, robot) = + let grid = grid_copy grid in + let _ = process_moves grid robot moves in + calc_score grid + +let _ = Aoc.main instrs_of_file [ (string_of_int, part) ] diff --git a/bin/dune b/bin/dune index 8bdfd57..7958c41 100644 --- a/bin/dune +++ b/bin/dune @@ -13,7 +13,8 @@ day2411 day2412 day2413 - day2414) + day2414 + day2415) (names day2401 day2402 @@ -28,5 +29,6 @@ day2411 day2412 day2413 - day2414) + day2414 + day2415) (libraries str aoc))