diff --git a/2022-aoc/src/d11.rs b/2022-aoc/src/d11.rs index 08c6f70..56d4075 100644 --- a/2022-aoc/src/d11.rs +++ b/2022-aoc/src/d11.rs @@ -4,19 +4,17 @@ use aoc_runner_derive::{aoc as aoc_run, aoc_generator}; #[derive(Debug, Clone, Default)] struct Monkey { - items: VecDeque, + items: VecDeque, op: Operation, - tmod: u32, + tmod: u128, target: (usize, usize), + business: u128, } -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default)] -struct Item(u32); - #[derive(Clone, Debug, PartialEq, Eq)] enum Operation { - Add(Option), - Mul(Option), + Add(Option), + Mul(Option), } impl Default for Operation { @@ -25,6 +23,32 @@ impl Default for Operation { } } +impl Monkey { + pub fn inspect(&mut self) -> Vec<(usize, u128)> { + let mut out = Vec::with_capacity(self.items.len()); + while let Some(item) = self.items.pop_front() { + let item = self.op(item) / 3; + if item % self.tmod == 0 { + out.push((self.target.0, item)); + } else { + out.push((self.target.1, item)); + } + self.business += 1; + } + self.items.clear(); + out + } + + fn op(&self, item: u128) -> u128 { + match self.op { + Operation::Add(Some(v)) => item + v, + Operation::Add(None) => item + item, + Operation::Mul(Some(v)) => item * v, + Operation::Mul(None) => item * item, + } + } +} + #[aoc_generator(day11)] fn parse_input(input: &str) -> Vec { let mut out = Vec::new(); @@ -35,6 +59,7 @@ fn parse_input(input: &str) -> Vec { let line = line.trim(); if line.starts_with("Monkey") { + monkey.business = 0; continue; } if line.starts_with("Starting") { @@ -65,11 +90,11 @@ fn parse_input(input: &str) -> Vec { out } -fn parse_items(items: &str) -> VecDeque { +fn parse_items(items: &str) -> VecDeque { let mut out = VecDeque::new(); let (_, items) = items.split_once(" items: ").unwrap(); for item in items.split(", ") { - out.push_back(Item(item.parse().unwrap())); + out.push_back(item.parse().unwrap()); } out } @@ -85,25 +110,63 @@ fn parse_operation(op: &str) -> Operation { } #[aoc_run(day11, part1)] -fn part1(troop: &[Monkey]) -> u32 { - 0 +fn part1(troop: &[Monkey]) -> u128 { + let mut troop = troop.to_owned(); + for _round in 0..20 { + for i in 0..troop.len() { + let monkey = &mut troop[i]; + let items = monkey.inspect(); + for (target, item) in items { + let m = &mut troop[target]; + m.items.push_back(item); + } + } + } + troop.sort_by(|m1, m2| m2.business.cmp(&m1.business)); + troop.iter().take(2).map(|m| m.business).product() } #[aoc_run(day11, part2)] -fn part2(troop: &[Monkey]) -> u32 { +fn part2(troop: &[Monkey]) -> u128 { 0 } #[cfg(test)] mod test { use super::*; - const INPUT: &str = ""; + const INPUT: &str = "Monkey 0: + Starting items: 79, 98 + Operation: new = old * 19 + Test: divisible by 23 + If true: throw to monkey 2 + If false: throw to monkey 3 + +Monkey 1: + Starting items: 54, 65, 75, 74 + Operation: new = old + 6 + Test: divisible by 19 + If true: throw to monkey 2 + If false: throw to monkey 0 + +Monkey 2: + Starting items: 79, 60, 97 + Operation: new = old * old + Test: divisible by 13 + If true: throw to monkey 1 + If false: throw to monkey 3 + +Monkey 3: + Starting items: 74 + Operation: new = old + 3 + Test: divisible by 17 + If true: throw to monkey 0 + If false: throw to monkey 1"; #[test] fn part1_test() { let v = parse_input(INPUT); - assert_eq!(part1(&v), 1); + assert_eq!(part1(&v), 10605); } #[test] @@ -111,4 +174,127 @@ mod test { let v = parse_input(INPUT); assert_eq!(part2(&v), 1); } + + #[test] + fn leah_test() { + let troop = parse_input( + "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", + ); + assert_eq!(part1(&troop), 78960); + } + + #[test] + fn rippy_part1() { + let input = "Monkey 0: + Starting items: 96, 60, 68, 91, 83, 57, 85 + Operation: new = old * 2 + Test: divisible by 17 + If true: throw to monkey 2 + If false: throw to monkey 5 + +Monkey 1: + Starting items: 75, 78, 68, 81, 73, 99 + Operation: new = old + 3 + Test: divisible by 13 + If true: throw to monkey 7 + If false: throw to monkey 4 + +Monkey 2: + Starting items: 69, 86, 67, 55, 96, 69, 94, 85 + Operation: new = old + 6 + Test: divisible by 19 + If true: throw to monkey 6 + If false: throw to monkey 5 + +Monkey 3: + Starting items: 88, 75, 74, 98, 80 + Operation: new = old + 5 + Test: divisible by 7 + If true: throw to monkey 7 + If false: throw to monkey 1 + +Monkey 4: + Starting items: 82 + Operation: new = old + 8 + Test: divisible by 11 + If true: throw to monkey 0 + If false: throw to monkey 2 + +Monkey 5: + Starting items: 72, 92, 92 + Operation: new = old * 5 + Test: divisible by 3 + If true: throw to monkey 6 + If false: throw to monkey 3 + +Monkey 6: + Starting items: 74, 61 + Operation: new = old * old + Test: divisible by 2 + If true: throw to monkey 3 + If false: throw to monkey 1 + +Monkey 7: + Starting items: 76, 86, 83, 55 + Operation: new = old + 4 + Test: divisible by 5 + If true: throw to monkey 4 + If false: throw to monkey 0"; + let troop = parse_input(input); + assert_eq!(part1(&troop), 56595); + } }