summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Jesus <adbjesus@gmail.com>2025-12-14 11:52:54 +0000
committerAlexandre Jesus <adbjesus@gmail.com>2025-12-14 11:52:54 +0000
commit55768f0f6f250983a6d78209e2ab53906a73e0e8 (patch)
tree4969c692c519f64e97ea209d4ee8548a79fceecb
parentfa3503c0495afd8f344a27a0229382eb40d3733a (diff)
downloadaoc2025-main.tar.gz
aoc2025-main.zip
Day 12HEADmain
-rw-r--r--bin/main.ml3
m---------data0
-rw-r--r--lib/day12.ml57
3 files changed, 59 insertions, 1 deletions
diff --git a/bin/main.ml b/bin/main.ml
index 0cbeabd..8552dda 100644
--- a/bin/main.ml
+++ b/bin/main.ml
@@ -48,9 +48,10 @@ let day_part_fn day part =
| 10, 2 -> Day10.part2
| 11, 1 -> Day11.part1
| 11, 2 -> Day11.part2
+ | 12, 1 -> Day12.part1
| _ ->
failwith
- (Format.sprintf "Day %d, part %d, has not yet been implemented\n" day
+ (Format.sprintf "Day %d, part %d, does not exist\n" day
part)
let () =
diff --git a/data b/data
-Subproject d860af9c1535386edd93edda14d8bfdbc897f92
+Subproject 99637220eb675eef6c6b2b06a49c3a55b8358ed
diff --git a/lib/day12.ml b/lib/day12.ml
new file mode 100644
index 0000000..bb687be
--- /dev/null
+++ b/lib/day12.ml
@@ -0,0 +1,57 @@
+(*
+ * SPDX-FileCopyrightText: Copyright 2025 Alexandre Jesus <https://adbjesus.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *)
+
+type puzzle = { n : int; m : int; q : int list }
+type shape = { n : int; m : int; g : bool array array }
+
+let parse ch =
+ let parse_puzzle s =
+ let d = String.trim s |> String.split_on_char ':' in
+ match d with
+ | sz :: (q :: []) ->
+ let n, m = Scanf.sscanf sz "%dx%d" (fun n m -> (n, m)) in
+ let q = String.trim q |> String.split_on_char ' ' |> List.map int_of_string in
+ { n; m; q}
+ | _ -> failwith ("Invalid puzzle: "^s)
+ in
+ let rec parse_shape l acc =
+ let make_res tl =
+ let g = List.rev acc |> Array.of_list in
+ let n = Array.length g in
+ let m = Array.length g.(0) in
+ (tl, { n; m; g })
+ in
+ match l with
+ | [] -> make_res []
+ | "" :: tl -> make_res tl
+ | line :: tl ->
+ let gl = String.to_seq line |> Seq.map (fun c -> c = '#') |> Array.of_seq in
+ parse_shape tl (gl :: acc)
+ in
+ let rec parse_all shapes puzzles l =
+ match l with
+ | [] -> (List.rev shapes, List.rev puzzles)
+ | "" :: tl -> parse_all shapes puzzles tl
+ | s :: tl ->
+ match Scanf.sscanf_opt s "%d:" (fun _ -> parse_shape tl []) with
+ | Some (l, shape) -> parse_all (shape :: shapes) puzzles l
+ | None -> parse_all shapes ((parse_puzzle s) :: puzzles) tl
+ in
+ In_channel.input_lines ch
+ |> parse_all [] []
+
+let solve_naive shapes puzzle =
+ (* This is NOT a solution to the general problem, but is enough for the given input *)
+ List.map2 (fun s c -> s.n * s.m * c) shapes puzzle.q
+ |> List.fold_left ( + ) 0
+ |> fun a -> if a <= puzzle.n * puzzle.m then 1 else 0
+
+let part1 ch =
+ let shapes, puzzles = parse ch in
+ List.map (solve_naive shapes) puzzles
+ |> List.fold_left ( + ) 0
+ |> Printf.printf "%d\n"
+