part 11
This commit is contained in:
75
11/main.ml
Normal file
75
11/main.ml
Normal 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
|
Reference in New Issue
Block a user