From 6d8fb621d1e93b83786890d6d9cb6f0d8defa8ae Mon Sep 17 00:00:00 2001 From: DJ O'Leary Date: Fri, 26 Jun 2026 18:04:09 +0200 Subject: refactor!: invert repo directory structure now is language first --- ocaml/lib/domain/d03p02.ml | 116 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 ocaml/lib/domain/d03p02.ml (limited to 'ocaml/lib/domain/d03p02.ml') diff --git a/ocaml/lib/domain/d03p02.ml b/ocaml/lib/domain/d03p02.ml new file mode 100644 index 0000000..88257d0 --- /dev/null +++ b/ocaml/lib/domain/d03p02.ml @@ -0,0 +1,116 @@ +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 + (** [highest_joltage bb] is an integer created from the two highest + digits in [bb]. + Raises: [Assert_failure] if [bb] is empty. *) + + 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 + + type highest = {one: Battery.t option; two: Battery.t option} + + let rec highest_joltage bb = + assert (List.length bb > 0) ; + match highest_joltage_aux {one= None; two= None} bb with + | {one= None; two= None} -> + 0 + | {one= Some x; two= Some y} -> + int_of_string (Battery.to_string x ^ Battery.to_string y) + | _ -> + failwith "highest_joltage must be two digits" + + and highest_joltage_aux acc = function + | [] -> + acc + | [elt] -> ( + match acc with + | {one= None; two= None} -> + {one= Some (Battery.of_int 0); two= Some elt} + | {one= Some first; two= None} -> + {one= Some first; two= Some elt} + | {one= None; two= Some second} -> + {one= Some second; two= Some elt} + | {one= Some first; two= Some second} -> + if elt > second then {one= Some first; two= Some elt} + else {one= Some first; two= Some second} ) + | h :: t -> + highest_joltage_aux + ( match acc with + | {one= None; two= None} -> + {one= Some h; two= None} + | {one= Some first; two= None} -> + let second = Battery.of_int 0 in + swap_if_higher first second h + | {one= Some first; two= Some second} -> + swap_if_higher first second h + | _ -> + failwith "this branch should be impossible" ) + t + + and swap_if_higher first second considering = + assert (first >= second) ; + let c_gt_f = Battery.compare considering first = 1 in + let c_gt_s = Battery.compare considering second = 1 in + match (c_gt_f, c_gt_s) with + | true, true -> + {one= Some considering; two= None} + | false, true -> + {one= Some first; two= Some considering} + | true, false -> + failwith "[second] should never be greater than [first]" + | false, false -> + {one= Some first; two= 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