From 9ed30f54f5d73fcdc9a56613baed28c53659aba5 Mon Sep 17 00:00:00 2001 From: DJ O'Leary Date: Sat, 6 Dec 2025 21:22:31 +0100 Subject: feat(2025d3p1): partial solution, getting the wrong answer Manually did entire real input and codified into tests but even sum of manual answer is wrong. Code fails for some lines of real input and these failing lines have been reduced into regression tests. work-in-progress: true --- 2025/ocaml/lib/application/d03p01.ml | 36 ++++++++++++- 2025/ocaml/lib/application/d03p01.mli | 2 + 2025/ocaml/lib/domain/d03p01.ml | 99 +++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 1 deletion(-) (limited to '2025/ocaml/lib') 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 -- cgit v1.2.3