AoC_2020/src/day15.rs

67 lines
1.4 KiB
Rust

use aoc_runner_derive::{aoc, aoc_generator};
type Data = Vec<usize>;
#[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::<Result<Vec<usize>, _>>()
.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);
}