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