summaryrefslogtreecommitdiff
path: root/ocaml/lib/year2025/day04/part02
diff options
context:
space:
mode:
Diffstat (limited to 'ocaml/lib/year2025/day04/part02')
-rw-r--r--ocaml/lib/year2025/day04/part02/solver.ml66
-rw-r--r--ocaml/lib/year2025/day04/part02/solver.mli4
2 files changed, 70 insertions, 0 deletions
diff --git a/ocaml/lib/year2025/day04/part02/solver.ml b/ocaml/lib/year2025/day04/part02/solver.ml
new file mode 100644
index 0000000..e92c982
--- /dev/null
+++ b/ocaml/lib/year2025/day04/part02/solver.ml
@@ -0,0 +1,66 @@
+let err_empty_input = "input is empty"
+
+let rec count_accessible_rolls matrix =
+ let count_paper lst = List.length @@ List.filter (fun c -> c = "@") lst in
+ let accessible_rolls_of_paper = ref [] in
+ let no_change = ref false in
+ while not !no_change do
+ let accessible_rolls_of_paper' = !accessible_rolls_of_paper in
+ count_accessible_rolls_aux matrix count_paper accessible_rolls_of_paper ;
+ if
+ List.length accessible_rolls_of_paper'
+ = List.length !accessible_rolls_of_paper
+ then no_change := true
+ done ;
+ List.length !accessible_rolls_of_paper
+
+and count_accessible_rolls_aux matrix count_paper accessible_rolls_of_paper =
+ for y = 0 to Array.length matrix - 1 do
+ for x = 0 to Array.length matrix.(y) - 1 do
+ if matrix.(y).(x) = "." then ()
+ else
+ let neighbour_coords =
+ Shared.Matrix.M.get_valid_neighbours matrix x y
+ in
+ let neighbours =
+ List.map
+ (fun (nx, ny) -> Shared.Matrix.M.get matrix nx ny)
+ neighbour_coords
+ in
+ let paper_count = count_paper neighbours in
+ let is_accessible = paper_count < 4 in
+ if is_accessible then
+ accessible_rolls_of_paper := (x, y) :: !accessible_rolls_of_paper ;
+ print_iteration_debug_msg x y neighbour_coords neighbours paper_count
+ is_accessible
+ done
+ done ;
+ List.iter
+ (fun (x', y') -> Shared.Matrix.M.set matrix x' y' ".")
+ !accessible_rolls_of_paper
+
+and print_iteration_debug_msg x y neighbour_coords neighbours paper_count
+ is_accessible =
+ Logs.debug (fun m ->
+ m
+ "coords=(%d,%d) neighbour_coords=[%s] neighbours=[%s] paper=%d \
+ is_accessible=%B"
+ x y
+ (List.fold_left
+ (fun acc (x, y) ->
+ if acc = "" then
+ " (" ^ string_of_int x ^ "," ^ string_of_int y ^ "); "
+ else acc ^ "(" ^ string_of_int x ^ "," ^ string_of_int y ^ "); " )
+ "" neighbour_coords )
+ (List.fold_left
+ (fun acc neighbour ->
+ if acc = "" then " " ^ neighbour ^ "; " else acc ^ neighbour ^ "; " )
+ "" neighbours )
+ paper_count is_accessible )
+
+let solve input () =
+ if input = "" then Error err_empty_input
+ else
+ let matrix = Shared.Matrix.M.of_string input in
+ let accessible_rolls_of_paper = count_accessible_rolls matrix in
+ Ok accessible_rolls_of_paper
diff --git a/ocaml/lib/year2025/day04/part02/solver.mli b/ocaml/lib/year2025/day04/part02/solver.mli
new file mode 100644
index 0000000..388ec56
--- /dev/null
+++ b/ocaml/lib/year2025/day04/part02/solver.mli
@@ -0,0 +1,4 @@
+val solve : string -> unit -> (int, string) result
+(** [solve input ()] is the solution for the second part of the fourth day of advent of code 2025 for [input].
+ The solution for an empty input is [Error msg].
+ Requires: [input] to be a string. *)