diff --git a/data/input-15.txt b/data/input-15.txt new file mode 100644 index 0000000..75e31b4 --- /dev/null +++ b/data/input-15.txt @@ -0,0 +1 @@ +15,5,1,4,7,0 diff --git a/data/output-15.txt b/data/output-15.txt new file mode 100644 index 0000000..10fcccf --- /dev/null +++ b/data/output-15.txt @@ -0,0 +1,2 @@ +1259 +689 diff --git a/src/day14.rs b/src/day14.rs index 4718805..8563fe0 100644 --- a/src/day14.rs +++ b/src/day14.rs @@ -1,4 +1,4 @@ -// ==== day 12 +// ==== day 14 use crate::utils; use anyhow::Result; diff --git a/src/day15.rs b/src/day15.rs new file mode 100644 index 0000000..548c330 --- /dev/null +++ b/src/day15.rs @@ -0,0 +1,41 @@ +// ==== day 15 + +use crate::utils; +use anyhow::Result; +use std::collections::BTreeMap; + +fn play_speaking_game(input: &[i64], n: usize) -> i64 { + let mut seen: BTreeMap = BTreeMap::new(); + let mut last_insert: Option = None; + + input.iter().enumerate().for_each(|(i, n)| { + last_insert = seen.insert(*n, i); + }); + + (seen.len()..n).fold(*input.last().unwrap(), |_, step| { + let num: i64 = match last_insert { + Some(prev_step) => (step - 1 - prev_step) as i64, + None => 0_i64, + }; + + last_insert = seen.insert(num, step); + num + }) +} + +// main +pub fn run() -> Result<(i64, i64)> { + let data: Vec = utils::read_file("data/input-15.txt")? + .trim() + .split(',') + .map(|s| s.parse::().expect("parse error")) + .collect(); + let answers = utils::read_i64s("data/output-15.txt")?; + + let p1 = play_speaking_game(&data, 2020); + let p2 = play_speaking_game(&data, 30000000); + + assert_eq!(p1, answers[0]); + assert_eq!(p2, answers[1]); + Ok((p1, p2)) +} diff --git a/src/main.rs b/src/main.rs index f818802..9c26cf3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ mod day10; mod day11; mod day12; mod day14; +mod day15; mod utils; // TODO @@ -39,5 +40,6 @@ fn main() -> Result<()> { println!("Day 11: {:?}", day11::run()?); println!("Day 12: {:?}", day12::run()?); println!("Day 14: {:?}", day14::run()?); + println!("Day 15: {:?}", day15::run()?); Ok(()) }