1
0
www.mikescher.com/www/statics/aoc/2020/15_solution.rs

115 lines
3.4 KiB
Rust

use crate::common::AdventOfCodeDay;
use std::collections::HashMap;
#[derive(Debug)]
pub struct Day15 {
input: Vec<u32>,
}
impl Day15 {
pub fn new() -> Self {
let input_bytes = include_bytes!("../res/15_input.txt");
let input_str = String::from_utf8_lossy(input_bytes);
let data = input_str
.split(',')
.map(|p| p.parse::<u32>().unwrap())
.collect::<Vec<u32>>();
Self {
input: data
}
}
}
struct MemoryIterator {
starters: Vec<u32>,
position: usize,
history: HashMap<u32, (usize, usize)>,
last_number: u32,
}
impl MemoryIterator {
pub fn new(initial: Vec<u32>) -> Self {
MemoryIterator {
starters: initial,
position: 1,
history: HashMap::new(),
last_number: 0,
}
}
}
impl Iterator for MemoryIterator {
type Item = u32;
fn next(&mut self) -> Option<u32> {
verboseln!();
let curr_pos = self.position;
self.position += 1;
verboseln!("[::] Get @ index {} (last_number = {})", curr_pos, self.last_number);
if curr_pos <= self.starters.len() {
self.last_number = self.starters[curr_pos-1];
verboseln!(" > history.insert({}, [{}, {}])", self.last_number, 0, curr_pos);
self.history.insert(self.last_number, (0, curr_pos));
verboseln!("Starter : {}", self.last_number);
return Some(self.last_number);
}
let (prev_1, prev_2) = self.history.get(&self.last_number).unwrap().clone();
if prev_1 == 0 {
self.last_number = 0;
if let Some((nprev_1, nprev_2)) = self.history.get_mut(&self.last_number) {
verboseln!(" > history.insert({}, [{}, {}]) [in-mem]", self.last_number, nprev_2, curr_pos);
*nprev_1 = *nprev_2;
*nprev_2 = curr_pos;
} else {
verboseln!(" > history.insert({}, [{}, {}])", self.last_number, 0, curr_pos);
self.history.insert(self.last_number, (0, curr_pos));
}
verboseln!("FirstTime : {}", self.last_number);
return Some(self.last_number);
} else {
self.last_number = (prev_2 - prev_1) as u32;
if let Some((nprev_1, nprev_2)) = self.history.get_mut(&self.last_number) {
verboseln!(" > history.insert({}, [{}, {}]) [in-mem]", self.last_number, nprev_2, curr_pos);
*nprev_1 = *nprev_2;
*nprev_2 = curr_pos;
} else {
verboseln!(" > history.insert({}, [{}, {}])", self.last_number, 0, curr_pos);
self.history.insert(self.last_number, (0, curr_pos));
}
verboseln!("Repeating : {} - {} = {}", prev_2, prev_1, self.last_number);
return Some(self.last_number);
}
}
}
impl AdventOfCodeDay for Day15 {
fn task_1(&self) -> String {
verboseln!("{:?}", self);
verboseln!("{:?}", MemoryIterator::new(self.input.clone()).skip(2018).take(5).collect::<Vec<u32>>());
return MemoryIterator::new(self.input.clone()).skip(2019).next().unwrap().to_string();
}
fn task_2(&self) -> String {
return MemoryIterator::new(self.input.clone()).skip(30_000_000 - 1).next().unwrap().to_string();
}
}