Add day 11

This commit is contained in:
Sebastian Knackstedt 2022-12-11 14:28:41 +01:00
parent c447b7fc71
commit c6be2c9a47
Signed by: sebastian
GPG Key ID: CDCD9AF904D93EF7
4 changed files with 213 additions and 0 deletions

View File

@ -49,4 +49,8 @@ path = "src/day9/main.rs"
name = "day10" name = "day10"
path = "src/day10/main.rs" path = "src/day10/main.rs"
[[bin]]
name = "day11"
path = "src/day11/main.rs"
[dependencies] [dependencies]

55
day11.txt Normal file
View File

@ -0,0 +1,55 @@
Monkey 0:
Starting items: 97, 81, 57, 57, 91, 61
Operation: new = old * 7
Test: divisible by 11
If true: throw to monkey 5
If false: throw to monkey 6
Monkey 1:
Starting items: 88, 62, 68, 90
Operation: new = old * 17
Test: divisible by 19
If true: throw to monkey 4
If false: throw to monkey 2
Monkey 2:
Starting items: 74, 87
Operation: new = old + 2
Test: divisible by 5
If true: throw to monkey 7
If false: throw to monkey 4
Monkey 3:
Starting items: 53, 81, 60, 87, 90, 99, 75
Operation: new = old + 1
Test: divisible by 2
If true: throw to monkey 2
If false: throw to monkey 1
Monkey 4:
Starting items: 57
Operation: new = old + 6
Test: divisible by 13
If true: throw to monkey 7
If false: throw to monkey 0
Monkey 5:
Starting items: 54, 84, 91, 55, 59, 72, 75, 70
Operation: new = old * old
Test: divisible by 7
If true: throw to monkey 6
If false: throw to monkey 3
Monkey 6:
Starting items: 95, 79, 79, 68, 78
Operation: new = old + 3
Test: divisible by 3
If true: throw to monkey 1
If false: throw to monkey 3
Monkey 7:
Starting items: 61, 97, 67
Operation: new = old + 4
Test: divisible by 17
If true: throw to monkey 0
If false: throw to monkey 5

27
day11_test.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

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]);
}