From 0000030073e8d691968511b49d369434f77f7674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Jane=C5=BEi=C4=8D?= Date: Sun, 22 Dec 2024 12:41:07 +0100 Subject: [PATCH] solution: day 22 --- data/examples/22.txt | 4 ++ src/bin/22.rs | 91 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 data/examples/22.txt create mode 100644 src/bin/22.rs diff --git a/data/examples/22.txt b/data/examples/22.txt new file mode 100644 index 000000000..201df76 --- /dev/null +++ b/data/examples/22.txt @@ -0,0 +1,4 @@ +1 +2 +3 +2024 diff --git a/src/bin/22.rs b/src/bin/22.rs new file mode 100644 index 000000000..f91bada --- /dev/null +++ b/src/bin/22.rs @@ -0,0 +1,91 @@ +use aoc::parsers::to_vec_map; +use hashbrown::{HashMap, HashSet}; + +fn pseudo_next(mut n: usize) -> usize { + n = ((n << 6) ^ n) % 16777216; + n = ((n >> 5) ^ n) % 16777216; + n = ((n << 11) ^ n) % 16777216; + n +} + +struct MonkeyTrader { + numbers: [usize; 2001], + sequences: HashMap<[isize; 4], usize>, +} + +impl MonkeyTrader { + fn new(seed: usize) -> Self { + let mut numbers = [0; 2001]; + numbers[0] = seed; + + let mut n = seed; + for num in numbers.iter_mut().skip(1) { + n = pseudo_next(n); + *num = n; + } + + let mut sequences = HashMap::new(); + for i in 4..2001 { + let mut key = [0; 4]; + for j in 1..=4 { + let d1 = numbers[i - 4 + j - 1] % 10; + let d2 = numbers[i - 4 + j] % 10; + let diff = d2 as isize - d1 as isize; + key[j - 1] = diff; + } + if sequences.contains_key(&key) { + continue; + } + *sequences.entry(key).or_default() = numbers[i] % 10; + } + + MonkeyTrader { numbers, sequences } + } +} + +pub fn part_one(input: &str) -> Option { + to_vec_map(input, '\n', MonkeyTrader::new) + .into_iter() + .map(|x| x.numbers[2000]) + .sum::() + .into() +} + +pub fn part_two(input: &str) -> Option { + let traders = to_vec_map(input, '\n', MonkeyTrader::new); + let key_union: HashSet<[isize; 4]> = traders + .iter() + .flat_map(|x| x.sequences.keys().cloned()) + .collect(); + + key_union + .into_iter() + .map(|k| { + traders + .iter() + .filter_map(|t| t.sequences.get(&k)) + .sum::() + }) + .max() +} + +aoc::solution!(22); + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_part_one() { + assert_eq!( + part_one(&aoc::template::read_file("examples", 22)), + Some(37990510) + ); + } + #[test] + fn test_part_two() { + assert_eq!( + part_two(&aoc::template::read_file("examples", 22)), + Some(23) + ); + } +}