From 524f02adfa2f5fba191b41c03182785a85e63695 Mon Sep 17 00:00:00 2001 From: JonOfUs Date: Sun, 11 Dec 2022 23:18:32 +0100 Subject: [PATCH] Day 11 --- res/11/input.txt | 55 ++++++++++++++++ src/days/d11.rs | 161 +++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 3 +- 3 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 res/11/input.txt create mode 100644 src/days/d11.rs diff --git a/res/11/input.txt b/res/11/input.txt new file mode 100644 index 0000000..78b36cc --- /dev/null +++ b/res/11/input.txt @@ -0,0 +1,55 @@ +Monkey 0: + Starting items: 89, 84, 88, 78, 70 + Operation: new = old * 5 + Test: divisible by 7 + If true: throw to monkey 6 + If false: throw to monkey 7 + +Monkey 1: + Starting items: 76, 62, 61, 54, 69, 60, 85 + Operation: new = old + 1 + Test: divisible by 17 + If true: throw to monkey 0 + If false: throw to monkey 6 + +Monkey 2: + Starting items: 83, 89, 53 + Operation: new = old + 8 + Test: divisible by 11 + If true: throw to monkey 5 + If false: throw to monkey 3 + +Monkey 3: + Starting items: 95, 94, 85, 57 + Operation: new = old + 4 + Test: divisible by 13 + If true: throw to monkey 0 + If false: throw to monkey 1 + +Monkey 4: + Starting items: 82, 98 + Operation: new = old + 7 + Test: divisible by 19 + If true: throw to monkey 5 + If false: throw to monkey 2 + +Monkey 5: + Starting items: 69 + Operation: new = old + 2 + Test: divisible by 2 + If true: throw to monkey 1 + If false: throw to monkey 3 + +Monkey 6: + Starting items: 82, 70, 58, 87, 59, 99, 92, 65 + Operation: new = old * 11 + Test: divisible by 5 + If true: throw to monkey 7 + If false: throw to monkey 4 + +Monkey 7: + Starting items: 91, 53, 96, 98, 68, 82 + Operation: new = old * old + Test: divisible by 3 + If true: throw to monkey 4 + If false: throw to monkey 2 diff --git a/src/days/d11.rs b/src/days/d11.rs new file mode 100644 index 0000000..29204b7 --- /dev/null +++ b/src/days/d11.rs @@ -0,0 +1,161 @@ +use std::fs; + +pub fn solve() { + let path = "res/11/input.txt"; + + let contents = fs::read_to_string(path).expect("I/O error, wrong path?"); + + let monk_strings: Vec<&str> = contents + .split("\n\n") + .collect(); + + let mut monkeys: Vec = monk_strings.iter().map(|monkey| Monkey::new(*monkey)).collect(); + let mut monkeys2 = monkeys.clone(); + let monkeys_num = monkeys.len(); + + (0..20).for_each(|_| { + (0..monkeys_num).for_each(|i| { + // get changed items + let new_items = monkeys[i].turn(monkeys_num, |x| x / 3); + // add items to correct monkeys + (0..monkeys_num).for_each(|i| { + new_items[i].iter().for_each(|item| monkeys[i].items.push(*item)) + }); + }) + }); + + monkeys.sort_by(|a, b| b.inspections.cmp(&a.inspections)); + let res = monkeys[0].inspections * monkeys[1].inspections; + + println!("Result 1: {res}"); + + + (0..10000).for_each(|_| { + (0..monkeys_num).for_each(|i| { + // get changed items, modulo them with common divider of divisible by tests + let common_divider: u64 = monkeys2.iter().map(|x| x.test_divisible_by).product(); + let new_items = monkeys2[i].turn(monkeys_num, |x| x % common_divider); + // add items to correct monkeys + (0..monkeys_num).for_each(|i| { + new_items[i].iter().for_each(|item| monkeys2[i].items.push(*item)) + }); + }) + }); + + monkeys2.sort_by(|a, b| b.inspections.cmp(&a.inspections)); + let res = monkeys2[0].inspections * monkeys2[1].inspections; + + println!("Result 2: {res}"); + + +} + +#[derive(Debug, PartialEq, Clone)] +enum Operation { + Mult, + Add +} + +#[derive(Debug, Clone)] +struct Monkey { + pub items: Vec, + operation_type: Operation, + operation_num: i32, + operation_quad: bool, + test_divisible_by: u64, + monkey_if_true: i32, + monkey_if_false: i32, + inspections: u64, +} + +impl Monkey { + pub fn new(input: &str) -> Self { + let mut monkey = Monkey { + items: Vec::::new(), + operation_type: Operation::Add, + operation_num: 0, + operation_quad: false, + test_divisible_by: 0, + monkey_if_true: 0, + monkey_if_false: 0, + inspections: 0 + }; + input.split("\n").filter(|line| *line != "").for_each(|line| { + let (ident, mut val) = line.split_at(line.find(":").unwrap()); + match ident { + " Starting items" => { + // remove whitespace and beginning, split by , + let val = val.replace(":","").replace(" ", ""); + monkey.items = val + .split(",") + .collect::>() + .iter() + .map(|i| (*i).parse::().unwrap()) + .collect() + }, + " Operation" => { + // parse operator, parse last word as number + let val = val.replace(": new = old ", ""); + let (op, num) = val.split_at(val.find(" ").unwrap()); + match op { + "+" => monkey.operation_type = Operation::Add, + "*" => monkey.operation_type = Operation::Mult, + _ => {} + } + if num == " old" { + monkey.operation_quad = true + } else { + monkey.operation_num = num.trim().parse::().unwrap(); + } + }, + " Test" => { + // parse last word as number + let words: Vec<&str> = val.split(" ").collect(); + monkey.test_divisible_by = words.last().unwrap().parse::().unwrap(); + }, + " If true" => { + // parse last word as number + let words: Vec<&str> = val.split(" ").collect(); + monkey.monkey_if_true = words.last().unwrap().parse::().unwrap(); + }, + " If false" => { + // parse last word as number + let words: Vec<&str> = val.split(" ").collect(); + monkey.monkey_if_false = words.last().unwrap().parse::().unwrap(); + }, + _ => {} + } + }); + + monkey + } + + pub fn turn(&mut self, monkeys: usize, func: impl Fn(u64) -> u64) -> Vec> { + let mut items: Vec> = (0..monkeys).map(|_| Vec::::new()).collect(); + self.items.iter().for_each(|item| { + let mut worry_level = *item; + // Operation + if self.operation_type == Operation::Add { + worry_level += self.operation_num as u64 + } else { + worry_level *= if self.operation_quad { + worry_level + } else { + self.operation_num as u64 + } + } + // Run func on worry level + let worry_level = func(worry_level); + // Test & push to other monkey + if worry_level % self.test_divisible_by as u64 == 0 { + items[self.monkey_if_true as usize].push(worry_level) + } else { + items[self.monkey_if_false as usize].push(worry_level) + } + self.inspections += 1 + }); + self.items.clear(); + + items + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index ae934d2..8be9365 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ pub mod days; fn main() { - days::d10::solve() + days::d11::solve() + //_all_days() } fn _all_days() {