2020-12-16 19:10:02 +00:00
|
|
|
use aoc_runner_derive::{aoc, aoc_generator};
|
2020-12-16 19:18:23 +00:00
|
|
|
use std::collections::HashMap;
|
2020-12-16 19:10:02 +00:00
|
|
|
type Data = Vec<usize>;
|
|
|
|
|
2020-12-16 19:18:23 +00:00
|
|
|
#[derive(Debug,Clone)]
|
2020-12-16 19:10:02 +00:00
|
|
|
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 {
|
2020-12-16 19:18:23 +00:00
|
|
|
let mut cache = vec![Seen::Never;num_turns];
|
2020-12-16 19:10:02 +00:00
|
|
|
let mut nums = start.to_vec();
|
|
|
|
let mut num=std::usize::MAX;
|
|
|
|
for i in 1..num_turns {
|
2020-12-16 19:18:23 +00:00
|
|
|
num = cache[nums[i - 1]].add(i);
|
2020-12-16 19:10:02 +00:00
|
|
|
if i >= nums.len() {
|
|
|
|
nums.push(num);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return num;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[aoc(day15, part1)]
|
|
|
|
pub fn solve_part1(input: &Data) -> usize {
|
|
|
|
return get_number(input, 2020);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[aoc(day15, part2)]
|
|
|
|
pub fn solve_part2(input: &Data) -> usize {
|
|
|
|
return get_number(input, 30_000_000);
|
|
|
|
}
|