summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAlexandre Jesus <adbjesus@gmail.com>2025-12-05 16:54:54 +0000
committerAlexandre Jesus <adbjesus@gmail.com>2025-12-05 16:55:24 +0000
commit2088b9e92611c43b6872fedf7d85a033a89f9c3b (patch)
tree846140d2f818c71ded1c44bd447035f7691635ea /lib
parent6d80c94eb7ea8ac0421df0832409b63be7c1246a (diff)
downloadaoc2025-2088b9e92611c43b6872fedf7d85a033a89f9c3b.tar.gz
aoc2025-2088b9e92611c43b6872fedf7d85a033a89f9c3b.zip
Day 4
Diffstat (limited to 'lib')
-rw-r--r--lib/day04.ml62
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/day04.ml b/lib/day04.ml
new file mode 100644
index 0000000..c4c3b78
--- /dev/null
+++ b/lib/day04.ml
@@ -0,0 +1,62 @@
+(*
+ * SPDX-FileCopyrightText: Copyright 2025 Alexandre Jesus <https://adbjesus.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *)
+
+let parse_data ch =
+ In_channel.input_all ch
+ |> String.trim
+ |> String.split_on_char '\n'
+ |> List.mapi (fun i s -> (i, s))
+ |> List.to_seq
+ |> Seq.flat_map (fun (i, s) ->
+ String.to_seq s
+ |> Seq.mapi (fun j v -> (j, v = '@'))
+ |> Seq.filter_map (fun (j, p) -> if p then Some ((i, j), 0) else None))
+ |> Hashtbl.of_seq
+
+let neighs =
+ [ (-1, -1); (-1, 0); (-1, 1); (0, -1); (0, 1); (1, -1); (1, 0); (1, 1) ]
+
+let neighs (i, j) = List.map (fun (a, b) -> (i + a, j + b)) neighs
+let count tbl k = (k, neighs k |> List.filter (Hashtbl.mem tbl) |> List.length)
+let counts tbl = Hashtbl.to_seq_keys tbl |> Seq.map (count tbl)
+
+let part1 ch =
+ parse_data ch
+ |> counts
+ |> Seq.filter (fun (_, v) -> v < 4)
+ |> Seq.length
+ |> Printf.printf "%d\n"
+
+let part2 ch =
+ let tbl = parse_data ch |> counts |> Hashtbl.of_seq in
+ let rec fn acc s =
+ let test k =
+ match Hashtbl.find_opt tbl k with
+ | None -> None
+ | Some v when v = 4 ->
+ Hashtbl.remove tbl k;
+ Some k
+ | Some v ->
+ Hashtbl.replace tbl k (v - 1);
+ None
+ in
+ match s with
+ | [] -> acc
+ | h :: t ->
+ neighs h
+ |> List.filter_map test
+ |> List.fold_left (fun (acc, s) k -> (acc + 1, k :: s)) (acc, t)
+ |> fun (acc, s) -> fn acc s
+ in
+ Hashtbl.to_seq tbl
+ |> List.of_seq
+ |> List.filter_map (fun (k, v) ->
+ if v < 4 then (
+ Hashtbl.remove tbl k;
+ Some k)
+ else None)
+ |> (fun s -> fn (List.length s) s)
+ |> Printf.printf "%d\n"