From ce6a85236687443516eeb76b0d74a0ada26186b8 Mon Sep 17 00:00:00 2001 From: John Costa Date: Sat, 14 Dec 2024 22:53:37 +0000 Subject: [PATCH] lantern fish??? --- AdventOfCode2024/bin/main.ml | 2 +- AdventOfCode2024/lib/day_11.ml | 64 ++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 AdventOfCode2024/lib/day_11.ml diff --git a/AdventOfCode2024/bin/main.ml b/AdventOfCode2024/bin/main.ml index 985beda..b5aea19 100644 --- a/AdventOfCode2024/bin/main.ml +++ b/AdventOfCode2024/bin/main.ml @@ -13,7 +13,7 @@ let read_lines name = let () = print_endline "\nAdvent of Code 2024"; let part1, part2 = - read_lines "./inputs/10.txt" |> AdventOfCode2024.Day_10.solve + read_lines "./inputs/11.txt" |> AdventOfCode2024.Day_11.solve in Printf.printf "Part 1: %s\nPart 2: %s\n" (string_of_int part1) (string_of_int part2) diff --git a/AdventOfCode2024/lib/day_11.ml b/AdventOfCode2024/lib/day_11.ml new file mode 100644 index 0000000..dfd9fb4 --- /dev/null +++ b/AdventOfCode2024/lib/day_11.ml @@ -0,0 +1,64 @@ +let line_to_numbers line = + String.split_on_char ' ' line |> List.map int_of_string + +module IntMap = Map.Make (Int) + +let num_of_digits num = (float_of_int num |> log10 |> int_of_float) + 1 + +let split_stone num = + let digits = num_of_digits num in + let num_str = string_of_int num in + let first_half = String.sub num_str 0 (digits / 2) |> int_of_string in + let second_half = + String.sub num_str (digits / 2) (digits / 2) |> int_of_string + in + (first_half, second_half) + +let upsert k v map = + IntMap.update k + (fun existing -> + match existing with None -> Some v | Some i -> Some (i + v)) + map + +let blink map = + IntMap.fold + (fun k v acc -> + if k == 0 then upsert 1 v acc + else if num_of_digits k mod 2 == 0 then + let first_stone, second_stone = split_stone k in + upsert first_stone v acc |> upsert second_stone v + else upsert (k * 2024) v acc) + map IntMap.empty + +let blink_times map times = + let rec loop acc times' = + match times' with 0 -> acc | t -> loop (blink acc) (t - 1) + in + loop map times + +let print_map map = IntMap.iter (Printf.printf "Key: %d, Value: %d\n") map + +let solve lines = + let line = List.nth lines 0 in + let nums = line_to_numbers line in + + let filled_map = + List.fold_left + (fun acc i -> + IntMap.update i + (fun item -> + match item with None -> Some 1 | Some in_map -> Some (in_map + 1)) + acc) + IntMap.empty nums + in + + let part1 = + blink_times filled_map 25 |> IntMap.to_list + |> List.fold_left (fun acc (_, v) -> acc + v) 0 + in + + let part2 = + blink_times filled_map 75 |> IntMap.to_list + |> List.fold_left (fun acc (_, v) -> acc + v) 0 + in + (part1, part2)