use aoc_runner_derive::{aoc, aoc_generator}; type Data = Vec; #[derive(Debug, Clone)] enum Seen { Never, Once(usize), Twice(usize, usize), } impl Default for Seen { fn default() -> Self { Seen::Never } } impl Seen { fn add(&mut self, n: usize) -> usize { *self = match self { Self::Never => Self::Once(n), Self::Once(i) => Self::Twice(*i, n), Self::Twice(_, i) => Self::Twice(*i, n), }; return self.diff(); } fn diff(&self) -> usize { match self { Seen::Never => unreachable!(), Seen::Once(_) => 0, Seen::Twice(a, b) => b - a, } } } #[aoc_generator(day15)] pub fn input_generator(input: &str) -> Data { input .split(',') .map(|num| num.parse()) .collect::, _>>() .unwrap() } fn get_number(start: &[usize], num_turns: usize) -> usize { let mut cache = vec![Seen::Never; num_turns]; let mut nums = start.to_vec(); let mut num = std::usize::MAX; for i in 1..num_turns { num = cache[nums[i - 1]].add(i); if i >= nums.len() { nums.push(num); } } return num; } #[aoc(day15, part1)] pub fn solve_part1(input: &[usize]) -> usize { return get_number(input, 2020); } #[aoc(day15, part2)] pub fn solve_part2(input: &[usize]) -> usize { return get_number(input, 30_000_000); }