feat: day 11 (35:03.72)

This commit is contained in:
Ashhhleyyy 2022-12-11 13:38:05 +00:00
parent f487f8ad0e
commit 837bf961ac
Signed by: ash
GPG key ID: 83B789081A0878FB
4 changed files with 211 additions and 1 deletions

55
.aoc-cache/11.txt Normal file
View file

@ -0,0 +1,55 @@
Monkey 0:
Starting items: 66, 71, 94
Operation: new = old * 5
Test: divisible by 3
If true: throw to monkey 7
If false: throw to monkey 4
Monkey 1:
Starting items: 70
Operation: new = old + 6
Test: divisible by 17
If true: throw to monkey 3
If false: throw to monkey 0
Monkey 2:
Starting items: 62, 68, 56, 65, 94, 78
Operation: new = old + 5
Test: divisible by 2
If true: throw to monkey 3
If false: throw to monkey 1
Monkey 3:
Starting items: 89, 94, 94, 67
Operation: new = old + 2
Test: divisible by 19
If true: throw to monkey 7
If false: throw to monkey 0
Monkey 4:
Starting items: 71, 61, 73, 65, 98, 98, 63
Operation: new = old * 7
Test: divisible by 11
If true: throw to monkey 5
If false: throw to monkey 6
Monkey 5:
Starting items: 55, 62, 68, 61, 60
Operation: new = old + 7
Test: divisible by 5
If true: throw to monkey 2
If false: throw to monkey 1
Monkey 6:
Starting items: 93, 91, 69, 64, 72, 89, 50, 71
Operation: new = old + 1
Test: divisible by 13
If true: throw to monkey 5
If false: throw to monkey 2
Monkey 7:
Starting items: 76, 50
Operation: new = old * old
Test: divisible by 7
If true: throw to monkey 4
If false: throw to monkey 6

119
src/bin/day_11.rs Normal file
View file

@ -0,0 +1,119 @@
use std::collections::VecDeque;
use aoc_2022::prelude::*;
#[derive(Clone, Debug)]
enum Op {
Add(i128),
Mult(i128),
Sq,
}
impl Op {
pub fn apply(&self, v: i128) -> i128 {
match self {
Op::Add(v2) => v + *v2,
Op::Mult(v2) => v * *v2,
Op::Sq => v * v,
}
}
}
#[derive(Clone, Debug)]
struct Monkey {
starting_items: VecDeque<i128>,
op: Op,
test: i128,
tr: usize,
fal: usize,
inspected: usize,
}
type Input = Vec<Monkey>;
fn parse(s: &str) -> Result<Input> {
let mut monkeys = vec![];
for monkey in s.split("\n\n") {
let lines = monkey.lines().collect::<Vec<_>>();
let starting_items = ints(lines[1]).into_iter().map(|v| v as i128).collect();
let op = if lines[2].contains("old * old") {
Op::Sq
} else if lines[2].contains("+") {
Op::Add(ints(lines[2])[0] as i128)
} else {
Op::Mult(ints(lines[2])[0] as i128)
};
let test = ints(lines[3])[0] as i128;
let tr = ints(lines[4])[0] as usize;
let fal = ints(lines[5])[0] as usize;
let monkey = Monkey {
starting_items,
op,
test,
tr,
fal,
inspected: 0,
};
monkeys.push(monkey);
}
Ok(monkeys)
}
#[aoc(day = 11, parse = parse, test_cases = ["day_11.txt"])]
fn day_11(input: Input) -> Result<()> {
// Part 1
let mut monkeys = input.clone();
for round in 0..20 {
for i in 0..monkeys.len() {
while let Some(item) = monkeys[i].starting_items.pop_front() {
monkeys[i].inspected += 1;
let (item, next) = {
let monkey = &monkeys[i];
let item = monkey.op.apply(item);
let item = item / 3;
(item, if item % monkey.test == 0 {
monkey.tr
} else {
monkey.fal
})
};
monkeys[next].starting_items.push_back(item);
}
}
}
monkeys.sort_by_cached_key(|m| m.inspected);
monkeys.reverse();
let monkey_business = monkeys[0].inspected * monkeys[1].inspected;
println!("Part one: {monkey_business}");
// Part 2
let mut monkeys = input.clone();
let mut md = 1;
for m in &input {
md *= m.test;
}
for round in 0..10_000 {
for i in 0..monkeys.len() {
while let Some(item) = monkeys[i].starting_items.pop_front() {
monkeys[i].inspected += 1;
let (item, next) = {
let monkey = &monkeys[i];
let item = monkey.op.apply(item);
let item = item % md;
(item, if item % monkey.test == 0 {
monkey.tr
} else {
monkey.fal
})
};
monkeys[next].starting_items.push_back(item);
}
}
}
monkeys.sort_by_cached_key(|m| m.inspected);
monkeys.reverse();
let monkey_business = monkeys[0].inspected * monkeys[1].inspected;
println!("Part two: {monkey_business}");
Ok(())
}

View file

@ -1,6 +1,7 @@
use std::path::Path; use std::path::Path;
use color_eyre::{eyre::eyre, Result}; use color_eyre::{eyre::eyre, Result};
use regex::Regex;
pub fn load_data<T, F: Fn(&str) -> Result<T>>(day: u8, parse: F) -> Result<T> { pub fn load_data<T, F: Fn(&str) -> Result<T>>(day: u8, parse: F) -> Result<T> {
let s = fetch_input(day)?; let s = fetch_input(day)?;
@ -35,6 +36,14 @@ pub fn fetch_input(day: u8) -> Result<String> {
} }
} }
pub fn ints(s: &str) -> Vec<isize> {
let re = Regex::new("([1-9][0-9]*|0)").unwrap();
re.find_iter(s).map(|m| {
m.as_str().parse().unwrap()
}).collect()
}
/// A writer that does nothing. can be used to have conditional debugging. /// A writer that does nothing. can be used to have conditional debugging.
pub struct NullWriter; pub struct NullWriter;
@ -49,7 +58,7 @@ impl std::io::Write for NullWriter {
} }
pub mod prelude { pub mod prelude {
pub use super::{data, load_data}; pub use super::{data, ints, load_data};
pub use color_eyre::{eyre::{bail, eyre}, Result}; pub use color_eyre::{eyre::{bail, eyre}, Result};
pub use aoc_proc::aoc; pub use aoc_proc::aoc;
} }

27
test_cases/day_11.txt 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