From 052d21f1328ecbe34dca4000d27bec985b42831e Mon Sep 17 00:00:00 2001 From: Max Nuding Date: Sun, 11 Dec 2022 15:03:07 +0000 Subject: [PATCH] Add day 11 --- Cargo.lock | 65 +++++++++++++++++++++++++++++ Cargo.toml | 1 + input/11.txt | 55 +++++++++++++++++++++++++ src/day11/mod.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 4 ++ 5 files changed, 229 insertions(+) create mode 100644 input/11.txt create mode 100644 src/day11/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 9fd0323..3ba8473 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,6 +28,7 @@ dependencies = [ "indextree", "itertools", "regex", + "sscanf", "tuple-map", ] @@ -80,6 +81,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "const_format" +version = "0.2.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7309d9b4d3d2c0641e018d449232f2e28f1b22933c137f157d3dbc14228b8c0e" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f47bf7270cf70d370f8f98c1abb6d2d4cf60a6845d30e05bfb90c6568650" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "core-foundation-sys" version = "0.8.3" @@ -184,6 +205,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.138" @@ -280,6 +307,38 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" +[[package]] +name = "sscanf" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887a5b09bbf30cc01d059ccb4b7a0b508a0cef3028df2f2ee0d745bc9e624c56" +dependencies = [ + "const_format", + "lazy_static", + "regex", + "sscanf_macro", +] + +[[package]] +name = "sscanf_macro" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b124cd4c68600cc3188a26987b1c3bed8cadcfd1be93124026096c668f2c0ee8" +dependencies = [ + "proc-macro2", + "quote", + "regex-syntax", + "strsim", + "syn", + "unicode-width", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "syn" version = "1.0.105" @@ -329,6 +388,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index a34e68f..1c874ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ chrono = "0.4.23" indextree = "4.5.0" itertools = "0.10.5" regex = "1.7.0" +sscanf = "0.4.0" tuple-map = "0.4.0" [features] diff --git a/input/11.txt b/input/11.txt new file mode 100644 index 0000000..58c5110 --- /dev/null +++ b/input/11.txt @@ -0,0 +1,55 @@ +Monkey 0: + Starting items: 54, 82, 90, 88, 86, 54 + Operation: new = old * 7 + Test: divisible by 11 + If true: throw to monkey 2 + If false: throw to monkey 6 + +Monkey 1: + Starting items: 91, 65 + Operation: new = old * 13 + Test: divisible by 5 + If true: throw to monkey 7 + If false: throw to monkey 4 + +Monkey 2: + Starting items: 62, 54, 57, 92, 83, 63, 63 + Operation: new = old + 1 + Test: divisible by 7 + If true: throw to monkey 1 + If false: throw to monkey 7 + +Monkey 3: + Starting items: 67, 72, 68 + Operation: new = old * old + Test: divisible by 2 + If true: throw to monkey 0 + If false: throw to monkey 6 + +Monkey 4: + Starting items: 68, 89, 90, 86, 84, 57, 72, 84 + Operation: new = old + 7 + Test: divisible by 17 + If true: throw to monkey 3 + If false: throw to monkey 5 + +Monkey 5: + Starting items: 79, 83, 64, 58 + Operation: new = old + 6 + Test: divisible by 13 + If true: throw to monkey 3 + If false: throw to monkey 0 + +Monkey 6: + Starting items: 96, 72, 89, 70, 88 + Operation: new = old + 4 + Test: divisible by 3 + If true: throw to monkey 1 + If false: throw to monkey 2 + +Monkey 7: + Starting items: 79 + Operation: new = old + 8 + Test: divisible by 19 + If true: throw to monkey 4 + If false: throw to monkey 5 \ No newline at end of file diff --git a/src/day11/mod.rs b/src/day11/mod.rs new file mode 100644 index 0000000..e04de5e --- /dev/null +++ b/src/day11/mod.rs @@ -0,0 +1,104 @@ +use crate::read; +use itertools::Itertools; + +#[derive(Debug, PartialEq, Eq, Clone, Hash)] +enum Operation { + Multiply(u64), + Add(u64), + Square, +} + +#[derive(Debug, PartialEq, Eq, Clone, Hash)] +struct Monkey { + pub items: Vec, + pub operation: Operation, + pub test: u64, + pub throw_to: [usize; 2], + pub inspected: usize, +} + +impl Monkey { + pub fn parse(s: &str) -> Self { + let (_, items, operation, operand, test, throw_true, throw_false) = sscanf::sscanf!( + s, + "Monkey {usize}: + Starting items: {str} + Operation: new = old {str} {str} + Test: divisible by {u64} + If true: throw to monkey {usize} + If false: throw to monkey {usize}" + ) + .unwrap(); + let items = items.split(", ").map(|i| i.parse().unwrap()).collect_vec(); + let operation = match operation { + "*" => match operand { + "old" => Operation::Square, + n => Operation::Multiply(n.parse().unwrap()), + }, + "+" => Operation::Add(operand.parse().unwrap()), + _ => unreachable!(), + }; + Self { + items, + operation, + test, + throw_to: [throw_true, throw_false], + inspected: 0, + } + } +} + +fn simulate(monkeys: &mut Vec, is_part_1: bool) { + let test_product: u64 = monkeys.iter().map(|m| m.test).product(); + let rounds = if is_part_1 { 20 } else { 10_000 }; + for _ in 0..rounds { + for i in 0..monkeys.len() { + let items = monkeys[i].items.clone(); + for mut item in items { + item = match monkeys[i].operation { + Operation::Square => item * item, + Operation::Add(n) => item + n, + Operation::Multiply(n) => item * n, + }; + item = if is_part_1 { + item / 3 + } else { + item % test_product + }; + let other_monkey = + monkeys[i].throw_to[if item % monkeys[i].test == 0 { 0 } else { 1 }]; + monkeys[other_monkey].items.push(item); + } + monkeys[i].inspected += monkeys[i].items.len(); + monkeys[i].items = Vec::new(); + } + } +} + +fn calculate_monkey_business(monkeys: &[Monkey]) -> usize { + monkeys + .iter() + .map(|m| m.inspected) + .sorted() + .rev() + .take(2) + .product() +} + +pub fn run() { + let input = read("11"); + let mut monkeys = input.split("\n\n").map(Monkey::parse).collect_vec(); + + #[cfg(feature = "part1")] + { + let monkeys = &mut monkeys.clone(); + simulate(monkeys, true); + println!("Day 11, Part 01: {}", calculate_monkey_business(monkeys)); + } + + #[cfg(feature = "part2")] + { + simulate(&mut monkeys, false); + println!("Day 11, Part 02: {}", calculate_monkey_business(&monkeys)); + } +} diff --git a/src/main.rs b/src/main.rs index d4e2e8f..efe2c81 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ mod day07; mod day08; mod day09; mod day10; +mod day11; mod puter; fn main() { @@ -46,6 +47,9 @@ fn main() { if cfg!(feature = "day10") || (cfg!(feature = "today") && today == 10) { day10::run(); } + if cfg!(feature = "day11") || (cfg!(feature = "today") && today == 11) { + day11::run(); + } println!("Finished, time taken: {:?}", now.elapsed()) }