use std::collections::HashMap; fn main() -> Result<(), Box> { // Part 1 let numbers = parse_numbers("1,20,11,6,12,0")?; let result = play(&numbers, 2020); println!("{}", result); // Part 2 let numbers = parse_numbers("1,20,11,6,12,0")?; let result = play(&numbers, 30000000); println!("{}", result); Ok(()) } fn parse_numbers(input: &str) -> Result, std::num::ParseIntError> { input.split(',').map(|number| number.parse()).collect() } fn play(numbers: &Vec, turns: usize) -> u32 { let mut said = HashMap::new(); for (turn, number) in numbers.iter().enumerate() { said.insert(*number, (turn + 1, 0)); } let mut last = *numbers.last().expect("Must have at least one number"); for turn in numbers.len()..turns { match said.get(&last) { Some((_, 0)) | None => { last = 0; let entry = said.entry(last).or_insert((0, 0)); *entry = (turn + 1, entry.0); } Some((last_turn, last_last_turn)) => { last = (last_turn - last_last_turn) as u32; let entry = said.entry(last).or_insert((0, 0)); *entry = (turn + 1, entry.0); } }; } last } #[cfg(test)] mod tests { use super::*; #[test] fn test_simple() -> Result<(), Box> { let input = "0,3,6"; let numbers = parse_numbers(input)?; let result = play(&numbers, 2020); assert_eq!(result, 436); Ok(()) } #[test] fn test_simple0() -> Result<(), Box> { let input = "1,3,2"; let numbers = parse_numbers(input)?; let result = play(&numbers, 2020); assert_eq!(result, 1); Ok(()) } #[test] fn test_simple1() -> Result<(), Box> { let input = "2,1,3"; let numbers = parse_numbers(input)?; let result = play(&numbers, 2020); assert_eq!(result, 10); Ok(()) } #[test] fn test_simple2() -> Result<(), Box> { let input = "1,2,3"; let numbers = parse_numbers(input)?; let result = play(&numbers, 2020); assert_eq!(result, 27); Ok(()) } #[test] fn test_simple3() -> Result<(), Box> { let input = "2,3,1"; let numbers = parse_numbers(input)?; let result = play(&numbers, 2020); assert_eq!(result, 78); Ok(()) } #[test] fn test_simple4() -> Result<(), Box> { let input = "3,2,1"; let numbers = parse_numbers(input)?; let result = play(&numbers, 2020); assert_eq!(result, 438); Ok(()) } #[test] fn test_simple5() -> Result<(), Box> { let input = "3,1,2"; let numbers = parse_numbers(input)?; let result = play(&numbers, 2020); assert_eq!(result, 1836); Ok(()) } }