Add day 11

This commit is contained in:
2022-12-11 14:28:41 +01:00
parent c447b7fc71
commit c6be2c9a47
4 changed files with 213 additions and 0 deletions

127
src/day11/main.rs Normal file
View File

@ -0,0 +1,127 @@
use std::collections::HashMap;
use std::str::FromStr;
use base::read_file;
#[derive(Debug, Copy, Clone)]
enum Op {
Add(u64),
Multiply(u64),
MultiplySelf,
}
impl FromStr for Op {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut iter = s.split_whitespace();
let _ = iter.next();
let op = iter.next().ok_or(())?.chars().next().ok_or(())?;
let value = iter.next().ok_or(())?;
if value == "old" && op == '*' {
return Ok(Op::MultiplySelf);
}
let value = value.parse::<u64>().ok().ok_or(())?;
return match op {
'+' => Ok(Op::Add(value)),
'*' => Ok(Op::Multiply(value)),
_ => Err(())
};
}
}
#[derive(Debug, Clone)]
struct Monkey {
id: usize,
items: Vec<u64>,
operation: Op,
test_value: u64,
next_success: usize,
next_failure: usize,
}
fn do_round<const F: u64>(monkeys: &mut Vec<Monkey>, monkey_counter: &mut HashMap<usize, u64>) {
let lcm = monkeys.iter().map(|m| m.test_value).reduce(|acc, item| acc * item).unwrap();
let mut items_to_add = HashMap::new();
for monkey in monkeys.iter_mut() {
if let Some(new_items) = items_to_add.remove(&monkey.id) {
for new_item in new_items {
monkey.items.push(new_item);
}
}
for item in &monkey.items {
*monkey_counter.entry(monkey.id).or_insert_with(|| 0) += 1;
let worry_level = match monkey.operation {
Op::Add(x) => *item + x,
Op::Multiply(x) => *item * x,
Op::MultiplySelf => *item * *item
} / F;
let worry_level = worry_level % lcm;
let test_successful = worry_level % monkey.test_value == 0;
items_to_add.entry(if test_successful {
monkey.next_success
} else {
monkey.next_failure
}).or_insert_with(|| Vec::new()).push(worry_level);
}
monkey.items.clear();
}
for monkey in monkeys.iter_mut() {
if let Some(new_items) = items_to_add.remove(&monkey.id) {
for new_item in new_items {
monkey.items.push(new_item);
}
}
}
}
fn main() {
let input = read_file("day11.txt");
let mut monkeys = vec![];
let monkeys_strings = input.chunks(7);
for monkeys_string in monkeys_strings {
let id = monkeys_string[0].replace(":", "").split_whitespace().collect::<Vec<_>>()[1].parse::<usize>().unwrap();
let items = monkeys_string[1].replace(",", "").split_whitespace().skip(2).filter_map(|s| s.parse::<u64>().ok()).collect::<Vec<_>>();
let operation = monkeys_string[2].split(" = ").filter_map(|s| s.parse::<Op>().ok()).next().unwrap();
let test_value = monkeys_string[3].split_whitespace().filter_map(|s| s.parse::<u64>().ok()).next().unwrap();
let next_success = monkeys_string[4].split_whitespace().filter_map(|s| s.parse::<usize>().ok()).next().unwrap();
let next_failure = monkeys_string[5].split_whitespace().filter_map(|s| s.parse::<usize>().ok()).next().unwrap();
monkeys.push(Monkey {
id,
items,
operation,
test_value,
next_success,
next_failure,
})
}
let mut monkey_counter = HashMap::new();
let mut monkey_copy = monkeys.clone();
for _ in 0..20 {
do_round::<3>(&mut monkey_copy, &mut monkey_counter);
}
let mut items = monkey_counter.values().collect::<Vec<_>>();
items.sort();
items.reverse();
println!("1. Result: {}", items[0] * items[1]);
monkey_counter.clear();
let mut monkey_copy = monkeys.clone();
for _ in 0..10000 {
do_round::<1>(&mut monkey_copy, &mut monkey_counter);
}
let mut items = monkey_counter.values().collect::<Vec<_>>();
items.sort();
items.reverse();
println!("2. Result: {}", items[0] * items[1]);
}