diff --git a/day11/Cargo.lock b/day11/Cargo.lock new file mode 100644 index 0000000..4ab9be8 --- /dev/null +++ b/day11/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "day11" +version = "0.1.0" diff --git a/day11/Cargo.toml b/day11/Cargo.toml new file mode 100644 index 0000000..8f5b9a5 --- /dev/null +++ b/day11/Cargo.toml @@ -0,0 +1,8 @@ +[package] +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] diff --git a/day11/data.txt b/day11/data.txt new file mode 100644 index 0000000..616cce7 --- /dev/null +++ b/day11/data.txt @@ -0,0 +1,55 @@ +Monkey 0: + Starting items: 83, 62, 93 + Operation: new = old * 17 + Test: divisible by 2 + If true: throw to monkey 1 + If false: throw to monkey 6 + +Monkey 1: + Starting items: 90, 55 + Operation: new = old + 1 + Test: divisible by 17 + If true: throw to monkey 6 + If false: throw to monkey 3 + +Monkey 2: + Starting items: 91, 78, 80, 97, 79, 88 + Operation: new = old + 3 + Test: divisible by 19 + If true: throw to monkey 7 + If false: throw to monkey 5 + +Monkey 3: + Starting items: 64, 80, 83, 89, 59 + Operation: new = old + 5 + Test: divisible by 3 + If true: throw to monkey 7 + If false: throw to monkey 2 + +Monkey 4: + Starting items: 98, 92, 99, 51 + Operation: new = old * old + Test: divisible by 5 + If true: throw to monkey 0 + If false: throw to monkey 1 + +Monkey 5: + Starting items: 68, 57, 95, 85, 98, 75, 98, 75 + Operation: new = old + 2 + Test: divisible by 13 + If true: throw to monkey 4 + If false: throw to monkey 0 + +Monkey 6: + Starting items: 74 + Operation: new = old + 4 + Test: divisible by 7 + If true: throw to monkey 3 + If false: throw to monkey 2 + +Monkey 7: + Starting items: 68, 64, 60, 68, 87, 80, 82 + Operation: new = old * 19 + Test: divisible by 11 + If true: throw to monkey 4 + If false: throw to monkey 5 diff --git a/day11/src/main.rs b/day11/src/main.rs new file mode 100644 index 0000000..de97874 --- /dev/null +++ b/day11/src/main.rs @@ -0,0 +1,97 @@ +use std::collections::VecDeque; + +#[derive(Debug, Clone)] +struct Monkey { + id: usize, + items: VecDeque, + operation: String, + divisor: u64, + true_monkey: usize, + false_monkey: usize, + inspected: usize, +} + +fn main() { + let contents = std::fs::read_to_string("data.txt").expect("Failed to read file"); + let mut monkeys = parse(contents.lines().collect()); + let mut monkeys2 = monkeys.clone(); + + let mut items = monkeys + .clone() + .into_iter() + .map(|m| m.items) + .collect::>>(); + let mut items2 = items.clone(); + + // Part 1 + run(&mut monkeys, &mut items, 3, 20); + + // Part 2 + run(&mut monkeys2, &mut items2, 1, 10000); +} + +fn run(monkeys: &mut Vec, items: &mut Vec>, divisor: u64, rounds: usize) -> () { + let total_prod = monkeys.iter().fold(1, |acc, m| m.divisor * acc); + for _ in 1..=rounds { + for m in 0..monkeys.len() { + let monkey = &mut monkeys[m]; + for _ in 0..items[m].len() { + let item = items[m].pop_front().unwrap(); + let new_item = operate(monkey.operation.as_str(), &item) % total_prod; + let new_item = new_item / divisor; + monkey.inspected += 1; + if new_item % monkey.divisor == 0 { + items[monkey.true_monkey].push_back(new_item); + } else { + items[monkey.false_monkey].push_back(new_item); + } + } + } + } + + let mut active = monkeys.iter().map(|m| m.inspected).collect::>(); + active.sort(); + active.reverse(); + let score = active.drain(0..2).fold(1, |acc, x| acc * x); + println!("\nactive: {:?}", active); + println!("score: {score}"); +} + +fn parse(lines: Vec<&str>) -> Vec { + lines + .chunks(7) + .into_iter() + .map(|lines| { + let items = lines[1] + .split(" ") + .skip(4) + .map(|i| i.get(0..2).unwrap().parse().unwrap()) + .collect::>(); + let operation = lines[2].split("=").collect::>()[1] + .trim() + .to_string(); + let divisor = lines[3].split(" ").last().unwrap().parse().unwrap(); + let true_monkey = lines[4].chars().last().unwrap().to_digit(10).unwrap() as usize; + let false_monkey = lines[5].chars().last().unwrap().to_digit(10).unwrap() as usize; + + Monkey { + id: lines[0].chars().nth(7).unwrap().to_digit(10).unwrap() as usize, + items, + operation, + divisor, + true_monkey, + false_monkey, + inspected: 0, + } + }) + .collect() +} + +fn operate(eq: &str, item: &u64) -> u64 { + match eq.split(" ").collect::>().as_slice() { + ["old", "*", "old"] => item * item, + ["old", "*", x] => item * x.parse::().unwrap(), + ["old", "+", x] => item + x.parse::().unwrap(), + _ => panic!("Invalid operation"), + } +} diff --git a/day11/test.txt b/day11/test.txt new file mode 100644 index 0000000..30e09e5 --- /dev/null +++ b/day11/test.txt @@ -0,0 +1,27 @@ +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