diff options
Diffstat (limited to 'ocaml/lib/year2025/day04')
| -rw-r--r-- | ocaml/lib/year2025/day04/part01/solver.ml | 48 | ||||
| -rw-r--r-- | ocaml/lib/year2025/day04/part01/solver.mli | 4 | ||||
| -rw-r--r-- | ocaml/lib/year2025/day04/part02/solver.ml | 66 | ||||
| -rw-r--r-- | ocaml/lib/year2025/day04/part02/solver.mli | 4 |
4 files changed, 122 insertions, 0 deletions
diff --git a/ocaml/lib/year2025/day04/part01/solver.ml b/ocaml/lib/year2025/day04/part01/solver.ml new file mode 100644 index 0000000..7cc54f6 --- /dev/null +++ b/ocaml/lib/year2025/day04/part01/solver.ml @@ -0,0 +1,48 @@ +let err_empty_input = "input is empty" + +let rec solve input () = + if input = "" then Error err_empty_input + else + let matrix = Shared.Matrix.M.of_string input in + let count_paper lst = List.length @@ List.filter (fun c -> c <> ".") lst in + let accessible_rolls_of_paper = ref 0 in + 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 (x', y') -> Shared.Matrix.M.get matrix x' y') + 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 := !accessible_rolls_of_paper + 1 ; + print_iteration_debug_msg x y neighbour_coords neighbours paper_count + is_accessible + done + done ; + Ok !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 ) diff --git a/ocaml/lib/year2025/day04/part01/solver.mli b/ocaml/lib/year2025/day04/part01/solver.mli new file mode 100644 index 0000000..873acff --- /dev/null +++ b/ocaml/lib/year2025/day04/part01/solver.mli @@ -0,0 +1,4 @@ +val solve : string -> unit -> (int, string) result +(** [solve input ()] is the solution for the first 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. *) 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. *) |
