do day 11

This commit is contained in:
Adam Jeniski 2022-12-11 14:29:47 -05:00
parent c3808cc473
commit 6f3444e68b
4 changed files with 275 additions and 0 deletions

55
2022/input/day_11.txt Normal file
View File

@ -0,0 +1,55 @@
Monkey 0:
Starting items: 66, 59, 64, 51
Operation: new = old * 3
Test: divisible by 2
If true: throw to monkey 1
If false: throw to monkey 4
Monkey 1:
Starting items: 67, 61
Operation: new = old * 19
Test: divisible by 7
If true: throw to monkey 3
If false: throw to monkey 5
Monkey 2:
Starting items: 86, 93, 80, 70, 71, 81, 56
Operation: new = old + 2
Test: divisible by 11
If true: throw to monkey 4
If false: throw to monkey 0
Monkey 3:
Starting items: 94
Operation: new = old * old
Test: divisible by 19
If true: throw to monkey 7
If false: throw to monkey 6
Monkey 4:
Starting items: 71, 92, 64
Operation: new = old + 8
Test: divisible by 3
If true: throw to monkey 5
If false: throw to monkey 1
Monkey 5:
Starting items: 58, 81, 92, 75, 56
Operation: new = old + 6
Test: divisible by 5
If true: throw to monkey 3
If false: throw to monkey 6
Monkey 6:
Starting items: 82, 98, 77, 94, 86, 81
Operation: new = old + 7
Test: divisible by 17
If true: throw to monkey 7
If false: throw to monkey 2
Monkey 7:
Starting items: 54, 95, 70, 93, 88, 93, 63, 50
Operation: new = old + 4
Test: divisible by 13
If true: throw to monkey 2
If false: throw to monkey 0

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

192
2022/src/day_11.rs Normal file
View File

@ -0,0 +1,192 @@
#[derive(Debug, Clone, Copy)]
enum Param {
Old,
Value(u64),
}
#[derive(Debug, Clone, Copy)]
enum Op {
Add,
Mulitply,
}
#[derive(Debug, Clone, Copy)]
struct Operation {
left: Param,
op: Op,
right: Param,
}
#[derive(Debug, Clone)]
struct Monkey {
id: usize,
items: Vec<u64>,
operation: Operation,
test: u64,
test_failed_go_to: usize,
test_passed_go_to: usize,
}
type Data = Vec<Monkey>;
type Output = u64;
fn parse(input: &str) -> Data {
input
.split("\n\n")
.map(|lines| {
let mut line_iter = lines.lines();
let id = {
let title_line = line_iter.next().unwrap();
let (_prefix, id_block) = title_line.split_once(' ').unwrap();
let (id, _rest) = id_block.split_once(':').unwrap();
id.parse().unwrap()
};
let items = {
let items_line = line_iter.next().unwrap();
let (_prefix, items) = items_line.split_once(": ").unwrap();
items.split(", ").map(|num| num.parse().unwrap()).collect()
};
let operation = {
let operation_line = line_iter.next().unwrap();
let (_prefix, rest) = operation_line.split_once("= ").unwrap();
let (left_str, rest) = rest.split_once(' ').unwrap();
let left = match left_str {
"old" => Param::Old,
s => Param::Value(s.parse().unwrap()),
};
let (op_str, right_str) = rest.split_once(' ').unwrap();
let op_char = op_str.chars().next().unwrap();
let op = match op_char {
'+' => Op::Add,
'*' => Op::Mulitply,
_ => panic!("expected + or *; got {}", op_str),
};
let right = match right_str {
"old" => Param::Old,
s => Param::Value(s.parse().unwrap()),
};
Operation { left, op, right }
};
let test = {
let test_line = line_iter.next().unwrap();
let (_prefix, num) = test_line.split_once("by ").unwrap();
num.parse().unwrap()
};
let test_passed_go_to = {
let passed_line = line_iter.next().unwrap();
let (_prefix, num) = passed_line.split_once("monkey ").unwrap();
num.parse().unwrap()
};
let test_failed_go_to = {
let failed_line = line_iter.next().unwrap();
let (_prefix, num) = failed_line.split_once("monkey ").unwrap();
num.parse().unwrap()
};
Monkey {
id,
items,
operation,
test,
test_failed_go_to,
test_passed_go_to,
}
})
.collect()
}
fn part_one(mut data: Data) -> Output {
let mut counts = vec![0; data.len()];
for _ in 1..=20 {
for i in 0..data.len() {
for j in 0..data[i].items.len() {
let left = match data[i].operation.left {
Param::Value(v) => v,
Param::Old => data[i].items[j],
};
let right = match data[i].operation.right {
Param::Value(v) => v,
Param::Old => data[i].items[j],
};
let new_value = match data[i].operation.op {
Op::Add => left + right,
Op::Mulitply => left * right,
} / 3;
if new_value % data[i].test == 0 {
let idx = data[i].test_passed_go_to;
data[idx].items.push(new_value);
} else {
let idx = data[i].test_failed_go_to;
data[idx].items.push(new_value);
}
}
counts[i] += data[i].items.len();
data[i].items.clear();
}
}
counts.sort();
counts.reverse();
counts[0] as u64 * counts[1] as u64
}
fn part_two(mut data: Data) -> Output {
let mut counts = vec![0; data.len()];
let test_gcd = data.iter().fold(1, |acc, curr| acc * curr.test);
for round in 1..=10000 {
for i in 0..data.len() {
for j in 0..data[i].items.len() {
let left = match data[i].operation.left {
Param::Value(v) => v,
Param::Old => data[i].items[j],
};
let right = match data[i].operation.right {
Param::Value(v) => v,
Param::Old => data[i].items[j],
};
let new_value = match data[i].operation.op {
Op::Add => left + right,
Op::Mulitply => left * right,
};
if new_value % data[i].test == 0 {
let idx = data[i].test_passed_go_to;
data[idx].items.push(new_value % test_gcd);
} else {
let idx = data[i].test_failed_go_to;
data[idx].items.push(new_value % test_gcd);
}
}
counts[i] += data[i].items.len();
data[i].items.clear();
}
match round {
1 | 20 | 1000 => {
dbg!(&counts, round);
}
_ => {}
}
}
counts.sort();
counts.reverse();
counts[0] as u64 * counts[1] as u64
}
advent_of_code_macro::generate_tests!(
day 11,
parse,
part_one,
part_two,
sample tests [10_605, 2_713_310_158],
star tests [90_294, 18_170_818_354]
);

View File

@ -9,3 +9,4 @@ mod day_07;
mod day_08; mod day_08;
mod day_09; mod day_09;
mod day_10; mod day_10;
mod day_11;