diff options
Diffstat (limited to '2025/ocaml/lib')
| -rw-r--r-- | 2025/ocaml/lib/application/d03p01.ml | 36 | ||||
| -rw-r--r-- | 2025/ocaml/lib/application/d03p01.mli | 2 | ||||
| -rw-r--r-- | 2025/ocaml/lib/domain/d03p01.ml | 99 |
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 |
