diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/day06.ml | 66 |
1 files changed, 66 insertions, 0 deletions
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" |
