This commit is contained in:
2024-12-12 01:06:02 +01:00
parent 547aac44fa
commit 14f445011c

75
11/main.ml Normal file
View File

@@ -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