This commit is contained in:
2024-12-22 22:59:51 +01:00
parent bb7ec19383
commit 66104db56e

72
22/main.ml Normal file
View File

@@ -0,0 +1,72 @@
open Printf;;
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 mix_and_prune x y =
Int.logand (Int.logxor x y) 0xffffff
let next_in_sequence x =
let x1 = mix_and_prune x (Int.shift_left x 6) in
let x2 = mix_and_prune x1 (Int.shift_right x1 5) in
mix_and_prune x2 (Int.shift_left x2 11)
let rec skip_sequence times x =
if times = 0 then
x
else skip_sequence (times - 1) (next_in_sequence x)
let make_indexing_array () =
Array.make 130321 0
let get_sequence_index (x1, x2, x3, x4) =
(x1 + 9) + (x2 + 9) * 19 + (x3 + 9) * 361 + (x4 + 9) * 6859
let mod10_diff x1 x2 =
(x1 mod 10) - (x2 mod 10)
module IntSet = Set.Make(Int)
let rec index_monkey_inner indexing_array already_occured_set current sequence seq_length =
if seq_length > 0 then
let index = get_sequence_index sequence in
let new_set = if IntSet.find_opt index already_occured_set |> Option.is_none then begin
indexing_array.(index) <- indexing_array.(index) + (current mod 10);
IntSet.add index already_occured_set
end else
already_occured_set in
let new_value = next_in_sequence current in
let diff = mod10_diff new_value current in
let (d1, d2, d3, _) = sequence in
index_monkey_inner indexing_array new_set new_value (diff, d1, d2, d3) (seq_length - 1)
let index_monkey indexing_array seq_length seed =
let s4 = next_in_sequence seed in
let s3 = next_in_sequence s4 in
let s2 = next_in_sequence s3 in
let s1 = next_in_sequence s2 in
let d1 = mod10_diff s1 s2 in
let d2 = mod10_diff s2 s3 in
let d3 = mod10_diff s3 s4 in
let d4 = mod10_diff s1 seed in
index_monkey_inner indexing_array IntSet.empty s1 (d1, d2, d3, d4) (seq_length - 4)
let decode_index index =
(index mod 19 - 9, (index / 19) mod 19 - 9, (index / 361) mod 19 - 9, (index / 6859) mod 19 - 9)
let () =
let () = Printexc.record_backtrace true in
let f = open_in "input.txt" in
let monkey_seeds = list_of_lines f |> List.map int_of_string in
let result = monkey_seeds
|> List.map (skip_sequence 2000)
|> List.fold_left Int.add 0 in
let indexing_array = make_indexing_array () in
List.iter (index_monkey indexing_array 2000) monkey_seeds;
let result2 = Array.fold_left Int.max 0 indexing_array in
printf "%d\n%d\n" result result2