Add day 11
This commit is contained in:
parent
c447b7fc71
commit
c6be2c9a47
@ -49,4 +49,8 @@ path = "src/day9/main.rs"
|
||||
name = "day10"
|
||||
path = "src/day10/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "day11"
|
||||
path = "src/day11/main.rs"
|
||||
|
||||
[dependencies]
|
||||
|
55
day11.txt
Normal file
55
day11.txt
Normal 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
27
day11_test.txt
Normal 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
127
src/day11/main.rs
Normal 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]);
|
||||
}
|
Loading…
Reference in New Issue
Block a user