From ec46327357938a7de74b6d6a83b9bb3d8b47c3ff Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Sun, 22 Dec 2024 09:52:22 +0000 Subject: [PATCH] 2024 day 22 tidy up. --- bin/day2422.ml | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/bin/day2422.ml b/bin/day2422.ml index ca3c796..1e1639c 100644 --- a/bin/day2422.ml +++ b/bin/day2422.ml @@ -1,15 +1,4 @@ -let next_secret secret = - let secret = secret * 64 lxor secret mod 16777216 in - let secret = secret / 32 lxor secret mod 16777216 in - let secret = secret * 2048 lxor secret mod 16777216 in - secret - -let nth_secret n secret = - let r = Aoc.apply_n n next_secret secret in - r - -let part1 n nums = List.map (nth_secret n) nums |> List.fold_left ( + ) 0 - +(** Module describing a tuple of four integers, used for the map keys later. *) module Int4Tuple = struct type t = int * int * int * int @@ -17,16 +6,31 @@ module Int4Tuple = struct end module Int4Map = Map.Make (Int4Tuple) +(** Map keyed by a tuple of 4 integers *) +(** [next_secret secret] returns the next secret value after [secret]. *) +let next_secret secret = + let secret = secret * 64 lxor secret mod 16777216 in + let secret = secret / 32 lxor secret mod 16777216 in + let secret = secret * 2048 lxor secret mod 16777216 in + secret + +let part1 n nums = + List.map (Aoc.apply_n n next_secret) nums |> List.fold_left ( + ) 0 + +(** [secret_list n secret] returns a list containing the [n] secrets after + [secret]. *) let secret_list n secret = let rec impl s () = Seq.Cons (s, impl (next_secret s)) in Seq.drop 1 (impl secret) |> Seq.take n |> List.of_seq -let rec find_sequence_costs map = +(** [find_sequence_values map lst] updates [map] to contain the value of the + sale for the first occurance in each sequence of 4 differences in [lst]. *) +let rec find_sequence_values map = let update_value amt = function None -> Some amt | x -> x in function | a :: b :: c :: d :: e :: t -> - find_sequence_costs + find_sequence_values (Int4Map.update (b - a, c - b, d - c, e - d) (update_value e) map) (b :: c :: d :: e :: t) | _ -> map @@ -40,19 +44,17 @@ let part2 n secrets = | None, None -> None in let costs = - List.map (secret_list n) secrets - |> List.map (List.map (fun x -> x mod 10)) - |> List.map (find_sequence_costs Int4Map.empty) - |> List.fold_left + List.map (secret_list n) secrets (* list of lists of secrets *) + |> List.map (List.map (fun x -> x mod 10)) (* list of lists of values *) + |> List.map (find_sequence_values Int4Map.empty) (* sequence -> value map *) + |> List.fold_left (* merge maps - adding values of same key *) (fun acc map -> Int4Map.merge merge_values acc map) Int4Map.empty in - Int4Map.fold (fun _ v acc -> max acc v) costs 0 + Int4Map.fold (fun _ v acc -> max acc v) costs 0 (* find max value *) let read_file fname = Aoc.strings_of_file fname |> List.map int_of_string let _ = Aoc.main read_file [ (string_of_int, part1 2000); (string_of_int, part2 2000) ] - -(* 424 too low *)