summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Jesus <adbjesus@gmail.com>2025-12-06 18:40:45 +0000
committerAlexandre Jesus <adbjesus@gmail.com>2025-12-06 18:40:45 +0000
commit5f4461fe96d07bef69cb59f5ce7182848340a951 (patch)
tree143fd15801757b1bdba69fd983f2e1aa77bef779
parentad818259ba31a98a3c00326894ebd71bbbde4667 (diff)
downloadaoc2025-5f4461fe96d07bef69cb59f5ce7182848340a951.tar.gz
aoc2025-5f4461fe96d07bef69cb59f5ce7182848340a951.zip
Day 6
-rw-r--r--bin/main.ml2
m---------data0
-rw-r--r--lib/day06.ml66
3 files changed, 68 insertions, 0 deletions
diff --git a/bin/main.ml b/bin/main.ml
index b5d7303..ebde0e3 100644
--- a/bin/main.ml
+++ b/bin/main.ml
@@ -36,6 +36,8 @@ let day_part_fn day part =
| 4, 2 -> Day04.part2
| 5, 1 -> Day05.part1
| 5, 2 -> Day05.part2
+ | 6, 1 -> Day06.part1
+ | 6, 2 -> Day06.part2
| _ ->
failwith
(Format.sprintf "Day %d, part %d, has not yet been implemented\n" day
diff --git a/data b/data
-Subproject 464e5178039496d1ed565669da7d13c14416a7d
+Subproject fade3292f33ea16f360782f0c55d3ce2b72ea5a
diff --git a/lib/day06.ml b/lib/day06.ml
new file mode 100644
index 0000000..7457c6d
--- /dev/null
+++ b/lib/day06.ml
@@ -0,0 +1,66 @@
+(*
+ * SPDX-FileCopyrightText: Copyright 2025 Alexandre Jesus <https://adbjesus.com>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *)
+
+let part1 ch =
+ let ops, nums =
+ In_channel.input_all ch
+ |> String.trim
+ |> String.split_on_char '\n'
+ |> List.map (String.split_on_char ' ')
+ |> List.map (List.filter (( <> ) ""))
+ |> List.rev
+ |> fun l -> (List.hd l, List.map (List.map int_of_string) (List.tl l))
+ in
+ List.fold_left
+ (fun acc l -> List.map2 (fun (r, op) v -> (op r v, op)) acc l)
+ (List.map (fun o -> if o = "*" then (1, ( * )) else (0, ( + ))) ops)
+ nums
+ |> List.map fst
+ |> List.fold_left ( + ) 0
+ |> Printf.printf "%d\n"
+
+let part2 ch =
+ (* another option would be to tranpose the numbers, but I wanted to avoid it *)
+ let parse_nums lines =
+ let czero = Char.code '0' in
+ let parse_digit c = if c = ' ' then None else Some (Char.code c - czero) in
+ let rec fn nums line =
+ match (nums, Seq.uncons line) with
+ | [], None -> []
+ | nums, None -> nums
+ | [], Some (v, tv) -> parse_digit v :: fn [] tv
+ | n :: tn, Some (v, tv) -> (
+ match (n, parse_digit v) with
+ | Some n, Some v -> Some ((n * 10) + v) :: fn tn tv
+ | Some n, None -> Some n :: fn tn tv
+ | None, Some v -> Some v :: fn tn tv
+ | None, None -> None :: fn tn tv)
+ in
+ List.fold_left (fun acc line -> fn acc (String.to_seq line)) [] lines
+ |> List.fold_left
+ (fun acc n ->
+ match n with
+ | None -> [] :: acc
+ | Some n -> (n :: List.hd acc) :: List.tl acc)
+ [ [] ]
+ |> List.filter (( <> ) [])
+ |> List.rev
+ in
+ let parse_ops line =
+ String.split_on_char ' ' line |> List.filter (( <> ) "")
+ in
+ let data = In_channel.input_all ch in
+ let lines = data |> String.split_on_char '\n' |> List.filter (( <> ) "") in
+ let rlines = List.rev lines in
+ let ops = parse_ops (List.hd rlines) in
+ let nums = parse_nums (List.rev (List.tl rlines)) in
+ List.map2
+ (fun op nums ->
+ if op = "*" then List.fold_left ( * ) 1 nums
+ else List.fold_left ( + ) 0 nums)
+ ops nums
+ |> List.fold_left ( + ) 0
+ |> Printf.printf "%d\n"