Untitled
fn solve01(lines: &str) -> (usize, Duration) { let now = Instant::now(); let sum = lines .lines() .map(|line| { let init_prng = PRNG::new(line.parse().unwrap()); let prng = (0..2000).fold(init_prng, |mut prng, _| { prng.next(); prng }); prng.secret }) .sum(); (sum, now.elapsed()) } fn solve02(lines: &str) -> (usize, Duration) { let now = Instant::now(); let mut sequence_sums = FxHashMap::default(); lines .lines() .map(|buyer_init| Buyer::new(buyer_init.parse().unwrap()).roi) .for_each(|buyer| { buyer.iter().for_each(|(&sequence, &value)| { sequence_sums .entry(sequence) .and_modify(|e| *e += value) .or_insert(value); }); }); let ans = *sequence_sums.values().max().unwrap(); (ans, now.elapsed()) } #[derive(Debug, Copy, Clone)] struct PRNG { secret: usize, } impl PRNG { const fn new(secret: usize) -> Self { Self { secret } } const fn mix(&mut self, a: usize) { self.secret ^= a; } const fn prune(&mut self) { self.secret %= 16777216; } const fn next(&mut self) { let mut temp = self.secret; self.mix(temp * 64); self.prune(); temp = self.secret; self.mix(temp / 32); self.prune(); temp = self.secret; self.mix(temp * 2048); self.prune(); } } #[derive(Debug, Clone)] struct Buyer { prng: PRNG, prices: [usize; 4], changes: [isize; 4], roi: FxHashMap<[isize; 4], usize>, } impl Buyer { fn new(init: usize) -> Self { let mut buyer = Self { prng: PRNG::new(init), prices: [0; 4], changes: [0; 4], roi: FxHashMap::default(), }; buyer.prices[0] = buyer.prng.secret % 10; buyer.populate(); buyer } fn populate(&mut self) { for i in 1..2001 { self.prng.next(); self.prices[i % 4] = self.prng.secret % 10; let change = self.prices[i % 4] as isize - self.prices[(i - 1) % 4] as isize; self.changes[i % 4] = change; if i >= 4 { let last_seq = [ self.changes[(i - 3) % 4], self.changes[(i - 2) % 4], self.changes[(i - 1) % 4], self.changes[i % 4], ]; self.roi.entry(last_seq).or_insert(self.prices[i % 4]); } } } }
Leave a Comment