summaryrefslogtreecommitdiff
path: root/2025/ocaml/lib
diff options
context:
space:
mode:
Diffstat (limited to '2025/ocaml/lib')
-rw-r--r--2025/ocaml/lib/application/d03p01.ml36
-rw-r--r--2025/ocaml/lib/application/d03p01.mli2
-rw-r--r--2025/ocaml/lib/domain/d03p01.ml99
3 files changed, 136 insertions, 1 deletions
diff --git a/2025/ocaml/lib/application/d03p01.ml b/2025/ocaml/lib/application/d03p01.ml
index b63679e..8e9c32c 100644
--- a/2025/ocaml/lib/application/d03p01.ml
+++ b/2025/ocaml/lib/application/d03p01.ml
@@ -15,6 +15,40 @@
5. Cast to int
Sum the result of each line
+
+ Tried: 17024 (hint: too low) - original
+ Tried: 17061 (hint: too low) - fixed second digit promotion - "343411" would give 41 instead of 44
+ Tried: 17081 (no hint given) - fixed second last digit promotion - "789" would give 79 insted of 89
+ Tried: 17091 (no hint given) - no change but found diff of 10 in failing test case
+ Tried: 17090 (no hint given) - no change but realised failing test case actually had a diff of 9 not 10 (have 56, want 65)
+ Tried: 17099 (no hint given) - no change but found additional failing test case (have 67, want 76)
+
+ Upper bound: 200 * 99 = 19800
*)
-let solve _ () = failwith "not started"
+open Domain.D03p01
+
+let to_lines s =
+ s |> String.split_on_char '\n' |> List.map String.trim
+ |> List.filter (fun l -> l <> "")
+
+let solve input () =
+ input |> to_lines |> List.to_seq
+ |> Seq.map BatteryBank.of_string
+ |> Seq.mapi (fun idx bb ->
+ let joltage = BatteryBank.highest_joltage bb in
+ Logs.debug (fun m ->
+ m "%d line=%s highest_joltage=%d" (idx + 1) (BatteryBank.pp bb)
+ joltage ) ;
+ joltage )
+ |> Seq.fold_left ( + ) 0
+
+let print_occurring_digits input () =
+ input |> to_lines |> List.to_seq
+ |> Seq.map BatteryBank.of_string
+ |> Seq.map BatteryBank.to_list
+ |> Seq.map (List.sort_uniq Battery.compare)
+ |> Seq.map BatteryBank.of_list
+ |> Seq.iteri (fun idx bb ->
+ Logs.debug (fun m -> m "%d %s" (idx + 1) (BatteryBank.pp bb)) ) ;
+ -1
diff --git a/2025/ocaml/lib/application/d03p01.mli b/2025/ocaml/lib/application/d03p01.mli
index 85f7e78..d875e40 100644
--- a/2025/ocaml/lib/application/d03p01.mli
+++ b/2025/ocaml/lib/application/d03p01.mli
@@ -2,3 +2,5 @@ val solve : string -> unit -> int
(** [solve input ()] is the solution for the first part of the third day of advent of code 2025 for [input].
The solution for an empty input is 0.
Requires: [input] to be a string. *)
+
+val print_occurring_digits : string -> unit -> int
diff --git a/2025/ocaml/lib/domain/d03p01.ml b/2025/ocaml/lib/domain/d03p01.ml
index e69de29..7f56bdc 100644
--- a/2025/ocaml/lib/domain/d03p01.ml
+++ b/2025/ocaml/lib/domain/d03p01.ml
@@ -0,0 +1,99 @@
+module Battery : sig
+ type t
+
+ val of_int : int -> t
+
+ val to_int : t -> int
+
+ val to_string : t -> string
+
+ val compare : t -> t -> int
+
+ val pp : t -> string
+end = struct
+ type t = int
+
+ let of_int i = i
+
+ let to_int b = b
+
+ let to_string = string_of_int
+
+ let compare = Int.compare
+
+ let pp = string_of_int
+end
+
+module BatteryBank : sig
+ type t
+
+ val highest_joltage : t -> int
+
+ val of_string : string -> t
+
+ val of_list : Battery.t list -> t
+
+ val to_list : t -> Battery.t list
+
+ val pp : t -> string
+end = struct
+ type t = Battery.t list
+
+ let rec highest_joltage bb =
+ match highest_joltage_aux (None, None) bb with
+ | None, None ->
+ 0
+ | Some x, Some y ->
+ int_of_string (Battery.to_string x ^ Battery.to_string y)
+ | _ ->
+ failwith "this branch should be impossible"
+
+ and highest_joltage_aux acc = function
+ | [] ->
+ acc
+ | h :: t ->
+ highest_joltage_aux
+ ( match acc with
+ | None, None ->
+ (Some h, None)
+ | Some first, None ->
+ (Some first, Some h)
+ | Some first, Some second ->
+ swap_if_higher first second h (List.length t = 0)
+ | _ ->
+ failwith "this branch should be impossible" )
+ t
+
+ and swap_if_higher first second considering is_end =
+ let c_gt_f = Battery.compare considering first = 1 in
+ let c_gt_s = Battery.compare considering second = 1 in
+ let f_gt_s = Battery.compare first second = 1 in
+ if c_gt_f && c_gt_s && f_gt_s then
+ if is_end then (Some first, Some considering) else (Some considering, None)
+ else if (not c_gt_f) && c_gt_s && f_gt_s then (Some first, Some considering)
+ else if c_gt_f && c_gt_s && not f_gt_s then
+ if is_end then (Some second, Some considering)
+ else (Some considering, None)
+ else if (not c_gt_f) && (not c_gt_s) && f_gt_s then (Some first, Some second)
+ else if c_gt_f && (not c_gt_s) && not f_gt_s then
+ (Some second, Some considering)
+ else (Some first, Some second)
+
+ let of_string s =
+ s |> String.to_seq
+ |> Seq.map (fun c -> Char.escaped c |> int_of_string |> Battery.of_int)
+ |> List.of_seq
+
+ let of_list lst = lst
+
+ let to_list bb = bb
+
+ let pp bb =
+ "[ "
+ ^ ( bb |> List.map Battery.pp
+ |> List.fold_left
+ (fun acc b ->
+ if acc = "" then b ^ ";" else Printf.sprintf "%s %s;" acc b )
+ "" )
+ ^ " ]"
+end