diff --git a/day11/Cargo.lock b/day11/Cargo.lock index 36ef88f..4ab9be8 100644 --- a/day11/Cargo.lock +++ b/day11/Cargo.lock @@ -2,288 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "block-padding", - "generic-array", -] - -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cpufeatures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" -dependencies = [ - "libc", -] - [[package]] name = "day11" version = "0.1.0" -dependencies = [ - "malachite", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "either" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" - -[[package]] -name = "embed-doc-image" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af36f591236d9d822425cb6896595658fa558fcebf5ee8accac1d4b92c47166e" -dependencies = [ - "base64", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "generic-array" -version = "0.14.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "itertools" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" -dependencies = [ - "either", -] - -[[package]] -name = "keccak" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "libc" -version = "0.2.138" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" - -[[package]] -name = "malachite" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80f6be3354f81a8566e001afe15cb774ce4c7f09ecc19f395f111943c3fba343" -dependencies = [ - "malachite-base", - "malachite-nz", - "malachite-q", -] - -[[package]] -name = "malachite-base" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e363f2fe3ec28952bd742c49e81183d00140bf45894a26d3dc2d8dfc126fda" -dependencies = [ - "itertools", - "rand", - "rand_chacha", - "ryu", - "sha3", -] - -[[package]] -name = "malachite-nz" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b0e6908a9ab7394526b00f2ec44816adfd47a72acbafdb0b3d0b16ec0ac6af" -dependencies = [ - "embed-doc-image", - "itertools", - "malachite-base", -] - -[[package]] -name = "malachite-q" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9850d5c4e7b95324d9e9c344f220e189af7cc78eb21c67ac47822757097bd9ce" -dependencies = [ - "itertools", - "malachite-base", - "malachite-nz", -] - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "proc-macro2" -version = "1.0.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom", - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core", -] - -[[package]] -name = "ryu" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" - -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer", - "digest", - "keccak", - "opaque-debug", -] - -[[package]] -name = "syn" -version = "1.0.105" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "typenum" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" - -[[package]] -name = "unicode-ident" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" diff --git a/day11/Cargo.toml b/day11/Cargo.toml index 4089b32..24c4940 100644 --- a/day11/Cargo.toml +++ b/day11/Cargo.toml @@ -3,10 +3,4 @@ name = "day11" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -malachite = "0.3.0" - -[profile.dev] -debug = 1 \ No newline at end of file +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html \ No newline at end of file diff --git a/day11/src/main.rs b/day11/src/main.rs index 67b72bd..10398fe 100644 --- a/day11/src/main.rs +++ b/day11/src/main.rs @@ -1,26 +1,16 @@ -use malachite::integer::Integer; -use malachite::num::arithmetic::traits::DivisibleBy; -use malachite::num::arithmetic::traits::Square; -use malachite::num::basic::traits::Zero; use std::collections::VecDeque; use std::str::FromStr; -/// Just to cut down on boilerplate for operations -/// with primitive types -fn big(n: usize) -> Integer { - n.into() -} - #[derive(Debug, PartialEq, Copy, Clone)] pub enum WorryType { Normal, Extra, } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Copy, Clone)] enum Operand { Old, - Literal(Integer) + Literal(usize), } #[derive(Debug)] @@ -33,24 +23,21 @@ impl Operation { fn new(operator: char, operand: &str) -> Self { let operand = match operand { "old" => Operand::Old, - _ => Operand::Literal(Integer::from_str(operand).unwrap()), + _ => Operand::Literal(usize::from_str(operand).unwrap()), }; - Operation { - operator, - operand, - } + Operation { operator, operand } } #[inline(always)] - fn run(&self, old: Integer) -> Integer { - let operand = self.operand.clone(); + fn run(&self, old: usize) -> usize { + let operand = self.operand; if operand == Operand::Old && self.operator == '*' { - return old.square(); + return old * old; } let other = match operand { - Operand::Old => old.clone(), + Operand::Old => old, Operand::Literal(other) => other, }; @@ -64,12 +51,12 @@ impl Operation { #[derive(Debug)] pub struct Monkey { - items: VecDeque, + items: VecDeque, operation: Operation, - test: Integer, + test: usize, pass_monkey: usize, fail_monkey: usize, - inspection_count: Integer, + inspection_count: usize, inspection_worry: WorryType, } @@ -78,9 +65,9 @@ impl Monkey { let lines: Vec<&str> = raw.lines().collect(); let item_parts: Vec<&str> = lines[1].split(": ").collect(); - let items: VecDeque = item_parts[1] + let items: VecDeque = item_parts[1] .split(", ") - .map(|i| i.parse::().unwrap()) + .map(|i| i.parse::().unwrap()) .collect(); let op_parts: Vec<&str> = lines[2].split(" = ").collect(); @@ -101,21 +88,18 @@ impl Monkey { Monkey { items, - operation: Operation::new( - operator.chars().next().unwrap(), - operand - ), - test: big(test), + operation: Operation::new(operator.chars().next().unwrap(), operand), + test, pass_monkey, fail_monkey, - inspection_count: Integer::ZERO, + inspection_count: 0, inspection_worry, } } #[inline(always)] - fn run_test(&self, item: &Integer) -> usize { - if item.divisible_by(&self.test) { + fn run_test(&self, item: &usize) -> usize { + if item % self.test == 0 { self.pass_monkey } else { self.fail_monkey @@ -123,12 +107,17 @@ impl Monkey { } #[inline(always)] - pub fn inspect(&mut self, item: Integer) -> (usize, Integer) { - self.inspection_count += big(1); + pub fn inspect(&mut self, mut item: usize, divisor_product: usize) -> (usize, usize) { + self.inspection_count += 1; let worry = if self.inspection_worry == WorryType::Normal { - self.operation.run(item) / big(3) + self.operation.run(item) / 3 } else { + // This is the whole key to keeping the number small enough to be practical. + // I don't really understand it, but I was sick of this not being finished, + // so I based the fix on + // https://fasterthanli.me/series/advent-of-code-2022/part-11 + item %= divisor_product; self.operation.run(item) }; @@ -138,7 +127,7 @@ impl Monkey { } #[inline(always)] - pub fn catch(&mut self, item: Integer) { + pub fn catch(&mut self, item: usize) { self.items.push_back(item); } } @@ -146,20 +135,27 @@ impl Monkey { #[derive(Debug)] pub struct MonkeyGame { monkeys: Vec, + divisor_product: usize, } impl MonkeyGame { pub fn from_file_str(file_str: &'static str, inspection_worry: WorryType) -> Self { let behaviors = file_str.split("\n\n"); + let monkeys: Vec = behaviors + .map(|m| Monkey::from_behavior(m, inspection_worry)) + .collect(); + + // The magic divisor for getting the result with normal integer sizes + let divisor_product = monkeys.iter().map(|m| m.test).product::(); + Self { - monkeys: behaviors - .map(|m| Monkey::from_behavior(m, inspection_worry)) - .collect(), + monkeys, + divisor_product, } } - fn throw(&mut self, item: Integer, to: usize) { + fn throw(&mut self, item: usize, to: usize) { self.monkeys[to].catch(item); } @@ -172,7 +168,7 @@ impl MonkeyGame { for m in 0..self.monkeys.len() { while let Some(worry) = self.monkeys[m].items.pop_front() { - let (monkey_idx, worry) = self.monkeys[m].inspect(worry); + let (monkey_idx, worry) = self.monkeys[m].inspect(worry, self.divisor_product); self.throw(worry, monkey_idx); } } @@ -181,8 +177,8 @@ impl MonkeyGame { self } - pub fn get_inspection_counts(&self) -> Vec { - let mut counts: Vec = self + pub fn get_inspection_counts(&self) -> Vec { + let mut counts: Vec = self .monkeys .iter() .map(|m| m.inspection_count.clone()) @@ -193,7 +189,7 @@ impl MonkeyGame { counts.into_iter().rev().collect() } - pub fn get_monkey_business(&self) -> Integer { + pub fn get_monkey_business(&self) -> usize { let inspections = self.get_inspection_counts(); inspections.get(0).unwrap() * inspections.get(1).unwrap() @@ -226,20 +222,10 @@ mod tests { let mut game = MonkeyGame::from_file_str(get_test_data(), WorryType::Normal); game.do_rounds(1); - assert_eq!( - game.monkeys[0].items, - VecDeque::from([big(20), big(23), big(27), big(26)]) - ); + assert_eq!(game.monkeys[0].items, VecDeque::from([20, 23, 27, 26])); assert_eq!( game.monkeys[1].items, - VecDeque::from([ - big(2080), - big(25), - big(167), - big(207), - big(401), - big(1046) - ]) + VecDeque::from([2080, 25, 167, 207, 401, 1046]) ); assert_eq!(game.monkeys[2].items, VecDeque::new()); assert_eq!(game.monkeys[3].items, VecDeque::new()); @@ -250,17 +236,9 @@ mod tests { let mut game = MonkeyGame::from_file_str(get_test_data(), WorryType::Normal); game.do_rounds(20); - assert_eq!(game.monkeys[0].inspection_count, big(101)); - assert_eq!(game.monkeys[3].inspection_count, big(105)); - assert_eq!(game.get_monkey_business(), big(10605)); - } - - fn monkey_10_000_rounds() { - let mut game = MonkeyGame::from_file_str(get_test_data(), WorryType::Normal); - game.do_rounds(10_000); - - assert_eq!(game.monkeys[0].inspection_count, big(52166)); - assert_eq!(game.monkeys[3].inspection_count, big(52013)); + assert_eq!(game.monkeys[0].inspection_count, 101); + assert_eq!(game.monkeys[3].inspection_count, 105); + assert_eq!(game.get_monkey_business(), 10605); } #[test] @@ -268,26 +246,27 @@ mod tests { let mut game = MonkeyGame::from_file_str(get_test_data(), WorryType::Extra); game.do_rounds(20); - assert_eq!(game.monkeys[0].inspection_count, big(99)); - assert_eq!(game.monkeys[3].inspection_count, big(103)); - assert_eq!(game.get_monkey_business(), big(10197)); + assert_eq!(game.monkeys[0].inspection_count, 99); + assert_eq!(game.monkeys[3].inspection_count, 103); + assert_eq!(game.get_monkey_business(), 10197); } - + #[test] fn monkey_1000_rounds_extra_worry() { let mut game = MonkeyGame::from_file_str(get_test_data(), WorryType::Extra); game.do_rounds(1000); - assert_eq!(game.monkeys[0].inspection_count, big(5204)); - assert_eq!(game.monkeys[3].inspection_count, big(5192)); + assert_eq!(game.monkeys[0].inspection_count, 5204); + assert_eq!(game.monkeys[3].inspection_count, 5192); } - + #[test] fn monkey_10_000_rounds_extra_worry() { let mut game = MonkeyGame::from_file_str(get_test_data(), WorryType::Extra); game.do_rounds(10_000); - assert_eq!(game.monkeys[0].inspection_count, big(52166)); - assert_eq!(game.monkeys[3].inspection_count, big(52013)); + assert_eq!(game.monkeys[0].inspection_count, 52166); + assert_eq!(game.monkeys[3].inspection_count, 52013); + assert_eq!(game.get_monkey_business(), 2713310158); } }