89 lines
2.5 KiB
Rust
89 lines
2.5 KiB
Rust
use std::io::Read;
|
|
use std::collections::HashMap;
|
|
|
|
|
|
fn init_memory<F: Read> (mut input: F) -> (HashMap<usize, usize>, usize) {
|
|
let mut buffer = String::new();
|
|
input.read_to_string(&mut buffer).unwrap();
|
|
let mut init: Vec<usize> = buffer.trim().split(',').map(|s| s.parse().unwrap()).collect();
|
|
let last = init.pop().unwrap();
|
|
let memory = init.iter().cloned().enumerate().map(|(turn, nb)| (nb, turn)).collect();
|
|
(memory, last)
|
|
}
|
|
|
|
fn play(mut memory: HashMap<usize, usize>, last_number: usize, max_turns: usize) -> usize {
|
|
let start = memory.len();
|
|
let end = max_turns - 1;
|
|
let mut last_number = last_number;
|
|
let mut current_number;
|
|
for turn in start..end {
|
|
current_number = memory.get(&last_number).map(|last_turn| turn - last_turn).unwrap_or(0);
|
|
memory.insert(last_number, turn);
|
|
last_number = current_number;
|
|
}
|
|
last_number
|
|
}
|
|
|
|
|
|
pub fn part1<F: Read> (input: F) {
|
|
let (memory, last) = init_memory(input);
|
|
println!("{}", play(memory, last, 2020));
|
|
}
|
|
|
|
|
|
// slow (~1min in debug mode / ~4s release mode) but working
|
|
pub fn part2<F: Read> (input: F) {
|
|
let (memory, last) = init_memory(input);
|
|
println!("{}", play(memory, last, 30000000));
|
|
}
|
|
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::*;
|
|
#[test]
|
|
pub fn test_parse() {
|
|
let input = "0,3,6\n".as_bytes();
|
|
let memory: HashMap<usize, usize> = [(0, 0), (3, 1)].iter().cloned().collect();
|
|
assert_eq!((memory, 6), init_memory(input));
|
|
}
|
|
|
|
#[test]
|
|
pub fn test_play() {
|
|
let mut test_cases = vec![
|
|
("0,3,6", 436),
|
|
("1,3,2", 1),
|
|
("2,1,3", 10),
|
|
("1,2,3", 27),
|
|
("2,3,1", 78),
|
|
("3,2,1", 438),
|
|
("3,1,2", 1836),
|
|
];
|
|
|
|
for (input, res) in test_cases.drain(..) {
|
|
let (memory, last) = init_memory(input.as_bytes());
|
|
assert_eq!(res, play(memory, last, 2020));
|
|
}
|
|
}
|
|
/* Too slow to run each time (~1min / iteration)
|
|
#[test]
|
|
pub fn test_play_again() {
|
|
let mut test_cases = vec![
|
|
("0,3,6", 175594),
|
|
("1,3,2", 2578),
|
|
("2,1,3", 3544142),
|
|
("1,2,3", 261214),
|
|
("2,3,1", 6895259),
|
|
("3,2,1", 18),
|
|
("3,1,2", 362),
|
|
];
|
|
|
|
for (input, res) in test_cases.drain(..) {
|
|
let (memory, last) = init_memory(input.as_bytes());
|
|
assert_eq!(res, play(memory, last, 30000000));
|
|
println!("passed")
|
|
}
|
|
}
|
|
*/
|
|
}
|