1
0
Fork 0

day 11 solution

main
Andrew Coleman 2022-12-12 15:01:45 -05:00
parent 920945061f
commit 59498dd72c
5 changed files with 254 additions and 0 deletions

55
2022/day11.txt Normal file
View File

@ -0,0 +1,55 @@
Monkey 0:
Starting items: 64
Operation: new = old * 7
Test: divisible by 13
If true: throw to monkey 1
If false: throw to monkey 3
Monkey 1:
Starting items: 60, 84, 84, 65
Operation: new = old + 7
Test: divisible by 19
If true: throw to monkey 2
If false: throw to monkey 7
Monkey 2:
Starting items: 52, 67, 74, 88, 51, 61
Operation: new = old * 3
Test: divisible by 5
If true: throw to monkey 5
If false: throw to monkey 7
Monkey 3:
Starting items: 67, 72
Operation: new = old + 3
Test: divisible by 2
If true: throw to monkey 1
If false: throw to monkey 2
Monkey 4:
Starting items: 80, 79, 58, 77, 68, 74, 98, 64
Operation: new = old * old
Test: divisible by 17
If true: throw to monkey 6
If false: throw to monkey 0
Monkey 5:
Starting items: 62, 53, 61, 89, 86
Operation: new = old + 8
Test: divisible by 11
If true: throw to monkey 4
If false: throw to monkey 6
Monkey 6:
Starting items: 86, 89, 82
Operation: new = old + 2
Test: divisible by 7
If true: throw to monkey 3
If false: throw to monkey 0
Monkey 7:
Starting items: 92, 81, 70, 96, 69, 84, 83
Operation: new = old + 4
Test: divisible by 3
If true: throw to monkey 4
If false: throw to monkey 5

168
2022/src/days/day11.rs Normal file
View File

@ -0,0 +1,168 @@
use anyhow::{anyhow, Result};
use std::collections::{BinaryHeap, VecDeque};
use std::fs;
#[derive(Default, Debug)]
enum Ops {
Plus(u64),
Mult(u64),
#[default]
Square,
}
#[derive(Default, Debug)]
struct Monkey {
items: VecDeque<u64>,
op: Ops,
test: u64,
result: [usize; 2],
}
pub fn run() -> Result<()> {
#[cfg(not(feature = "test_input"))]
let file_contents = fs::read_to_string("day11.txt")?;
#[cfg(feature = "test_input")]
let file_contents = fs::read_to_string("tests/day11.txt")?;
let mut monkeys: Vec<Monkey> = Vec::with_capacity(8);
let mut lines = file_contents.lines();
while let Some(line) = lines.next() {
if line.is_empty() {
continue;
}
if line.starts_with("Monkey") {
let mut m = Monkey::default();
for i in lines.next().unwrap().split_whitespace().skip(2) {
if let Some(s) = i.strip_suffix(",") {
m.items.push_back(s.parse::<u64>().unwrap());
} else {
m.items.push_back(i.parse::<u64>().unwrap());
}
}
let mut ops = lines.next().unwrap().split_whitespace().skip(4);
let op_symbol = ops.next().unwrap();
let op_val = ops.next().unwrap();
match op_symbol {
"*" => {
m.op = if op_val == "old" {
Ops::Square
} else {
let val: u64 = op_val.parse().unwrap();
Ops::Mult(val)
}
}
"+" => {
let val: u64 = op_val.parse().unwrap();
m.op = Ops::Plus(val);
}
_ => return Err(anyhow!("invalid op code")),
}
let t = lines
.next()
.unwrap()
.split_whitespace()
.skip(3)
.next()
.unwrap()
.parse::<u64>()
.unwrap();
m.test = t;
let tmonkey: usize = lines
.next()
.unwrap()
.split_whitespace()
.skip(5)
.next()
.unwrap()
.parse()
.unwrap();
let fmonkey: usize = lines
.next()
.unwrap()
.split_whitespace()
.skip(5)
.next()
.unwrap()
.parse()
.unwrap();
m.result = [tmonkey, fmonkey];
monkeys.push(m);
}
}
part_one_items(&mut monkeys);
part_two_items(&mut monkeys);
Ok(())
}
fn match_op(op: &Ops, old: u64) -> u64 {
match op {
Ops::Plus(t) => old + t,
Ops::Mult(t) => old * t,
Ops::Square => old * old,
}
}
fn part_one_items(monkeys: &mut Vec<Monkey>) {
let mut inspections: Vec<usize> = Vec::with_capacity(8);
let mut items: Vec<VecDeque<u64>> = monkeys.iter().map(|m| m.items.clone()).collect();
for _ in 1..=20 {
for m in 0..monkeys.len() {
if let None = inspections.get(m) {
inspections.push(0);
}
while let Some(item) = items[m].pop_front() {
inspections[m] += 1;
let score = (match_op(&monkeys[m].op, item) as f32 / 3.0).floor() as u64;
if score % monkeys[m].test == 0 {
items[monkeys[m].result[0]].push_back(score);
} else {
items[monkeys[m].result[1]].push_back(score);
}
}
}
}
let mut bh: BinaryHeap<usize> = BinaryHeap::from(inspections);
let one = bh.pop().unwrap();
let two = bh.pop().unwrap();
println!("part one {}*{}={}", one, two, one * two);
}
fn part_two_items(monkeys: &mut Vec<Monkey>) {
let mut inspections: Vec<usize> = Vec::with_capacity(8);
let mut items: Vec<VecDeque<u64>> = monkeys.iter().map(|m| m.items.clone()).collect();
#[cfg(feature = "test_input")]
let cd = 96577;
// grep Test day11.txt | awk 'BEGIN { S=1} { S=S*$4} END {print S}'
#[cfg(not(feature = "test_input"))]
let cd = 9699690;
for _ in 1..=10000 {
for m in 0..monkeys.len() {
if let None = inspections.get(m) {
inspections.push(0);
}
while let Some(item) = items[m].pop_front() {
inspections[m] += 1;
let score = match_op(&monkeys[m].op, item);
if score % monkeys[m].test == 0 {
items[monkeys[m].result[0]].push_back(score % cd);
} else {
items[monkeys[m].result[1]].push_back(score % cd);
}
}
}
}
let mut bh: BinaryHeap<usize> = BinaryHeap::from(inspections);
let one = bh.pop().unwrap();
let two = bh.pop().unwrap();
println!("part two {}*{}={}", one, two, one * two);
}

View File

@ -1,5 +1,6 @@
pub mod day1;
pub mod day10;
pub mod day11;
pub mod day2;
pub mod day3;
pub mod day4;

View File

@ -42,6 +42,9 @@ fn run_day(number: i32) -> Result<()> {
10 => {
days::day10::run()?;
}
11 => {
days::day11::run()?;
}
_ => return Err(anyhow!("Invalid day provided")),
}
Ok(())

27
2022/tests/day11.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