From 14f445011cb323a951dbee0b72ac6e924665b3de Mon Sep 17 00:00:00 2001 From: Acvaxoort Date: Thu, 12 Dec 2024 01:06:02 +0100 Subject: [PATCH] part 11 --- 11/main.ml | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 11/main.ml diff --git a/11/main.ml b/11/main.ml new file mode 100644 index 0000000..9535fa3 --- /dev/null +++ b/11/main.ml @@ -0,0 +1,75 @@ +open Printf;; +open Map;; + +let rec list_of_lines in_file = + try + let line = input_line in_file in + line :: list_of_lines(in_file) + with End_of_file -> + close_in in_file; + [] + +let rec parse_int_list sep str = + let list1 = (List.filter (fun a -> String.length a != 0) (String.split_on_char sep str)) in + List.map int_of_string list1 + +let stone_tick value = + if value = 0 then + [1] + else + let digits_str = string_of_int value in + let num_digits = String.length digits_str in + if num_digits mod 2 = 0 then + let half_num_digits = num_digits / 2 in + let n1 = int_of_string (String.sub digits_str 0 half_num_digits) in + let n2 = int_of_string (String.sub digits_str half_num_digits half_num_digits) in + [n1; n2] + else + [value * 2024] + +let transform_stones_naive stones = + stones + |> List.map stone_tick + |> List.concat + +module IntMap = Map.Make(Int) + +let add_counter_in_map n prev_opt = + match prev_opt with + | Some prev_count -> Some (prev_count + n) + | None -> Some n + +let update_counter_in_map_accumulator n acc_map key = + IntMap.update key (add_counter_in_map n) acc_map + +let transform_stone_with_count stone_value count acc_map = + let stone_result = stone_tick stone_value in + List.fold_left (update_counter_in_map_accumulator count) acc_map stone_result + +let transform_stones stone_counts_map = + IntMap.fold transform_stone_with_count stone_counts_map IntMap.empty + +let total_counters_in_map map = + IntMap.fold (fun _ counter acc -> acc + counter) map 0 + +let rec apply_n_times n f arg = + if n <= 0 then + arg + else + apply_n_times (n-1) f (f arg) + +let () = + let f = open_in "input.txt" in + let stones = f + |> list_of_lines + |> List.hd + |> parse_int_list ' ' in +let result = stones + |> apply_n_times 25 transform_stones_naive + |> List.length in +printf "%d\n" result; +let result2 = stones + |> List.fold_left (update_counter_in_map_accumulator 1) IntMap.empty + |> apply_n_times 75 transform_stones + |> total_counters_in_map in +printf "%d\n" result2