1
0
Fork 0

Solve day 11

This commit is contained in:
Lars Martens 2022-12-11 11:55:54 +01:00
parent 4f7ed8d228
commit 6ddb4c4c8f
Signed by: haselkern
GPG key ID: B5CF1F363C179AD4
3 changed files with 228 additions and 0 deletions

55
input/11 Normal file
View file

@ -0,0 +1,55 @@
Monkey 0:
Starting items: 75, 63
Operation: new = old * 3
Test: divisible by 11
If true: throw to monkey 7
If false: throw to monkey 2
Monkey 1:
Starting items: 65, 79, 98, 77, 56, 54, 83, 94
Operation: new = old + 3
Test: divisible by 2
If true: throw to monkey 2
If false: throw to monkey 0
Monkey 2:
Starting items: 66
Operation: new = old + 5
Test: divisible by 5
If true: throw to monkey 7
If false: throw to monkey 5
Monkey 3:
Starting items: 51, 89, 90
Operation: new = old * 19
Test: divisible by 7
If true: throw to monkey 6
If false: throw to monkey 4
Monkey 4:
Starting items: 75, 94, 66, 90, 77, 82, 61
Operation: new = old + 1
Test: divisible by 17
If true: throw to monkey 6
If false: throw to monkey 1
Monkey 5:
Starting items: 53, 76, 59, 92, 95
Operation: new = old + 2
Test: divisible by 19
If true: throw to monkey 4
If false: throw to monkey 3
Monkey 6:
Starting items: 81, 61, 75, 89, 70, 92
Operation: new = old * old
Test: divisible by 3
If true: throw to monkey 0
If false: throw to monkey 1
Monkey 7:
Starting items: 81, 86, 62, 87
Operation: new = old + 8
Test: divisible by 13
If true: throw to monkey 3
If false: throw to monkey 5

27
input/11-test Normal file
View file

@ -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

146
src/bin/11.rs Normal file
View file

@ -0,0 +1,146 @@
use std::{collections::VecDeque, fmt, str::FromStr};
use aoc2022::*;
use itertools::Itertools;
const INPUT: &str = include_str!("../../input/11");
fn main() {
let mut troop = Troop::from_input();
troop.play(20, 3);
solved_level_1(troop.level());
let mut troop = Troop::from_input();
troop.play(10000, 1);
solved_level_2(troop.level());
}
#[derive(Debug)]
struct Troop(Vec<Monkey>);
impl Troop {
fn level(&self) -> usize {
let mut inspections = self.0.iter().map(|m| m.inspected).collect_vec();
inspections.sort();
inspections.reverse();
inspections[0] * inspections[1]
}
fn play(&mut self, rounds: usize, divider: u64) {
for _ in 0..rounds {
for monkey in 0..self.0.len() {
self.monkey_play(monkey, divider);
}
}
}
fn monkey_play(&mut self, monkey: usize, divider: u64) {
self.0[monkey].inspected += self.0[monkey].items.len();
let modulus: u64 = self.0.iter().map(|m| m.test).product();
while let Some(mut item) = self.0[monkey].items.pop_front() {
let target = {
let monkey = &self.0[monkey];
match monkey.op {
Operation::Add(n) => item += n,
Operation::Mul(n) => item *= n,
Operation::Square => item *= item,
};
item /= divider;
item %= modulus;
if item % monkey.test == 0 {
monkey.throw_true
} else {
monkey.throw_false
}
};
self.0[target].items.push_back(item);
}
}
fn from_input() -> Self {
let mut monkeys = Vec::new();
// Placeholder while building.
let mut current = Monkey {
items: VecDeque::new(),
op: Operation::Add(0u8.into()),
test: 0,
throw_true: 0,
throw_false: 0,
inspected: 0,
};
for (i, line) in INPUT.lines().enumerate() {
match i % 7 {
0 | 6 => { /* Monkey index or empty line can be ignored */ }
1 => {
let (_, items) = line.split_once(": ").unwrap();
current.items = items
.split(", ")
.map(|item| item.parse().unwrap())
.collect();
}
2 => {
current.op = if line.contains("old * old") {
Operation::Square
} else if line.contains('*') {
Operation::Mul(line.parse_last())
} else {
Operation::Add(line.parse_last())
}
}
3 => current.test = line.parse_last(),
4 => current.throw_true = line.parse_last(),
5 => {
current.throw_false = line.parse_last();
// This is the final line
monkeys.push(current.clone());
}
i => unreachable!("{i} is impossible to get in mod 7"),
}
}
Self(monkeys)
}
}
#[derive(Debug, Clone)]
struct Monkey {
items: VecDeque<u64>,
op: Operation,
test: u64,
throw_true: usize,
throw_false: usize,
inspected: usize,
}
#[derive(Debug, Clone)]
enum Operation {
Add(u64),
Mul(u64),
Square,
}
/// Helper trait to make code more readable.
/// Parses the last element from a whitespace separated str.
trait ParseLast<T> {
fn parse_last(self) -> T;
}
impl<'a, T> ParseLast<T> for &'a str
where
T: FromStr,
T::Err: fmt::Debug,
{
fn parse_last(self) -> T {
self.split_ascii_whitespace()
.last()
.unwrap()
.parse()
.unwrap()
}
}