changeset 74:b007d28fb585

Day 16 Part 2
author Lewin Bormann <lbo@spheniscida.de>
date Fri, 29 Dec 2023 10:06:45 +0100
parents 2c6477929e58
children 6e7829d7eee6
files 2023/day16.ml
diffstat 1 files changed, 29 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/2023/day16.ml	Fri Dec 29 09:53:19 2023 +0100
+++ b/2023/day16.ml	Fri Dec 29 10:06:45 2023 +0100
@@ -134,9 +134,37 @@
     Array.fold field.tiles ~init:0 ~f
 end
 
+module Part2 = struct
+  (* return a list of all edge tiles with according directions *)
+  let all_edge_tiles field =
+    let top = List.init field.cols ~f:(fun c -> (0, c, South))
+    and bottom = List.init field.cols ~f:(fun c -> (field.rows - 1, c, North))
+    and left = List.init field.rows ~f:(fun r -> (r, 0, East))
+    and right = List.init field.rows ~f:(fun r -> (r, field.cols - 1, West)) in
+    List.concat [ top; bottom; left; right ]
+
+  (* reset the beam on all tiles *)
+  let reset_field field =
+    let f i tile = field.tiles.(i) <- { tile with beam = 0 } in
+    Array.iteri field.tiles ~f
+
+  (* count the number of energized tiles starting from the given position *)
+  let count_energized field (init : Part1.pos) =
+    reset_field field;
+    Part1.traverse field [ init ];
+    Part1.count_energized field
+
+  (* find the maximum number of energized tiles starting from any edge tile *)
+  let max_energized field =
+    let f max init = Int.max max (count_energized field init) in
+    List.fold (all_edge_tiles field) ~init:0 ~f
+end
+
 let () =
   let input = In_channel.input_all In_channel.stdin in
   let field = Parse.parse_input input in
   Part1.traverse field Part1.initial_state;
   let count = Part1.count_energized field in
-  Out_channel.printf "Part 1: %d\n" count
+  Out_channel.printf "Part 1: %d\n" count;
+  let max = Part2.max_energized field in
+  Out_channel.printf "Part 2: %d\n" max