Advent of Code solutions
at main 86 lines 2.2 kB view raw
1use std::collections::{HashMap, HashSet}; 2 3use advent_core::{day_stuff, ex_for_day, Day}; 4 5pub struct Day22; 6 7fn next_secret(mut num: usize) -> usize { 8 num = ((num * 64) ^ num) % 16777216; 9 num = ((num / 32) ^ num) % 16777216; 10 num = ((num * 2048) ^ num) % 16777216; 11 num 12} 13 14fn secret_n_times(init: usize, times: usize) -> usize { 15 let mut num = init; 16 for _ in 0..times { 17 num = next_secret(num); 18 } 19 num 20} 21 22fn get_all_four_unique_changes(init: usize, times: usize) -> HashMap<[isize; 4], usize> { 23 let mut last = 0; 24 let mut changes = Vec::with_capacity(times + 1); 25 let mut curr = init; 26 for _ in 0..times { 27 curr = next_secret(curr); 28 let val = curr % 10; 29 changes.push(((val as isize) - (last as isize), val)); 30 last = val; 31 } 32 33 changes 34 .windows(4) 35 .fold(HashMap::with_capacity(times / 4), |mut acc, w| { 36 let changes = [w[0].0, w[1].0, w[2].0, w[3].0]; 37 let final_val = w[3].1; 38 acc.entry(changes).or_insert(final_val); 39 acc 40 }) 41} 42 43impl Day for Day22 { 44 day_stuff!(22, "37327623", "23", Vec<usize>); 45 46 fn part_1(input: Self::Input) -> Option<String> { 47 let ans = input 48 .into_iter() 49 .map(|init| secret_n_times(init, 2000)) 50 .sum::<usize>(); 51 52 Some(ans.to_string()) 53 } 54 55 fn part_2(input: Self::Input) -> Option<String> { 56 let change_to_val = input 57 .into_iter() 58 .map(|init| get_all_four_unique_changes(init, 2000)) 59 .collect::<Vec<_>>(); 60 let all_changes = change_to_val 61 .iter() 62 .flat_map(|h| h.keys().copied()) 63 .collect::<HashSet<_>>(); 64 65 let ans = all_changes 66 .into_iter() 67 .map(|c| { 68 change_to_val 69 .iter() 70 .map(|h| h.get(&c).unwrap_or(&0)) 71 .sum::<usize>() 72 }) 73 .max() 74 .unwrap(); 75 76 Some(ans.to_string()) 77 } 78 79 fn parse_input(input: &str) -> Self::Input { 80 input 81 .trim() 82 .lines() 83 .map(|l| l.parse::<usize>().unwrap()) 84 .collect() 85 } 86}