Add day 11
This commit is contained in:
104
src/day11/mod.rs
Normal file
104
src/day11/mod.rs
Normal file
@ -0,0 +1,104 @@
|
||||
use crate::read;
|
||||
use itertools::Itertools;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
||||
enum Operation {
|
||||
Multiply(u64),
|
||||
Add(u64),
|
||||
Square,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
||||
struct Monkey {
|
||||
pub items: Vec<u64>,
|
||||
pub operation: Operation,
|
||||
pub test: u64,
|
||||
pub throw_to: [usize; 2],
|
||||
pub inspected: usize,
|
||||
}
|
||||
|
||||
impl Monkey {
|
||||
pub fn parse(s: &str) -> Self {
|
||||
let (_, items, operation, operand, test, throw_true, throw_false) = sscanf::sscanf!(
|
||||
s,
|
||||
"Monkey {usize}:
|
||||
Starting items: {str}
|
||||
Operation: new = old {str} {str}
|
||||
Test: divisible by {u64}
|
||||
If true: throw to monkey {usize}
|
||||
If false: throw to monkey {usize}"
|
||||
)
|
||||
.unwrap();
|
||||
let items = items.split(", ").map(|i| i.parse().unwrap()).collect_vec();
|
||||
let operation = match operation {
|
||||
"*" => match operand {
|
||||
"old" => Operation::Square,
|
||||
n => Operation::Multiply(n.parse().unwrap()),
|
||||
},
|
||||
"+" => Operation::Add(operand.parse().unwrap()),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
Self {
|
||||
items,
|
||||
operation,
|
||||
test,
|
||||
throw_to: [throw_true, throw_false],
|
||||
inspected: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn simulate(monkeys: &mut Vec<Monkey>, is_part_1: bool) {
|
||||
let test_product: u64 = monkeys.iter().map(|m| m.test).product();
|
||||
let rounds = if is_part_1 { 20 } else { 10_000 };
|
||||
for _ in 0..rounds {
|
||||
for i in 0..monkeys.len() {
|
||||
let items = monkeys[i].items.clone();
|
||||
for mut item in items {
|
||||
item = match monkeys[i].operation {
|
||||
Operation::Square => item * item,
|
||||
Operation::Add(n) => item + n,
|
||||
Operation::Multiply(n) => item * n,
|
||||
};
|
||||
item = if is_part_1 {
|
||||
item / 3
|
||||
} else {
|
||||
item % test_product
|
||||
};
|
||||
let other_monkey =
|
||||
monkeys[i].throw_to[if item % monkeys[i].test == 0 { 0 } else { 1 }];
|
||||
monkeys[other_monkey].items.push(item);
|
||||
}
|
||||
monkeys[i].inspected += monkeys[i].items.len();
|
||||
monkeys[i].items = Vec::new();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn calculate_monkey_business(monkeys: &[Monkey]) -> usize {
|
||||
monkeys
|
||||
.iter()
|
||||
.map(|m| m.inspected)
|
||||
.sorted()
|
||||
.rev()
|
||||
.take(2)
|
||||
.product()
|
||||
}
|
||||
|
||||
pub fn run() {
|
||||
let input = read("11");
|
||||
let mut monkeys = input.split("\n\n").map(Monkey::parse).collect_vec();
|
||||
|
||||
#[cfg(feature = "part1")]
|
||||
{
|
||||
let monkeys = &mut monkeys.clone();
|
||||
simulate(monkeys, true);
|
||||
println!("Day 11, Part 01: {}", calculate_monkey_business(monkeys));
|
||||
}
|
||||
|
||||
#[cfg(feature = "part2")]
|
||||
{
|
||||
simulate(&mut monkeys, false);
|
||||
println!("Day 11, Part 02: {}", calculate_monkey_business(&monkeys));
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ mod day07;
|
||||
mod day08;
|
||||
mod day09;
|
||||
mod day10;
|
||||
mod day11;
|
||||
mod puter;
|
||||
|
||||
fn main() {
|
||||
@ -46,6 +47,9 @@ fn main() {
|
||||
if cfg!(feature = "day10") || (cfg!(feature = "today") && today == 10) {
|
||||
day10::run();
|
||||
}
|
||||
if cfg!(feature = "day11") || (cfg!(feature = "today") && today == 11) {
|
||||
day11::run();
|
||||
}
|
||||
println!("Finished, time taken: {:?}", now.elapsed())
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user