diff --git a/day-15/Cargo.lock b/day-15/Cargo.lock new file mode 100644 index 0000000..1135a55 --- /dev/null +++ b/day-15/Cargo.lock @@ -0,0 +1,78 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "day-15" +version = "0.1.0" +dependencies = [ + "indoc", +] + +[[package]] +name = "indoc" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47741a8bc60fb26eb8d6e0238bbb26d8575ff623fdc97b1a2c00c050b9684ed8" +dependencies = [ + "indoc-impl", + "proc-macro-hack", +] + +[[package]] +name = "indoc-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce046d161f000fffde5f432a0d034d0341dc152643b2598ed5bfce44c4f3a8f0" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", + "unindent", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "1.0.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "unindent" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7" diff --git a/day-15/Cargo.toml b/day-15/Cargo.toml new file mode 100644 index 0000000..5d876d5 --- /dev/null +++ b/day-15/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "day-15" +version = "0.1.0" +authors = ["Tristan Daniƫl Maat "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +indoc = "0.3" diff --git a/day-15/src/main.rs b/day-15/src/main.rs new file mode 100644 index 0000000..8aa0f24 --- /dev/null +++ b/day-15/src/main.rs @@ -0,0 +1,121 @@ +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(()) + } +}