Day 11
parent
b6eaa973c4
commit
083636f274
|
@ -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
|
|
@ -0,0 +1,55 @@
|
||||||
|
Monkey 0:
|
||||||
|
Starting items: 89, 73, 66, 57, 64, 80
|
||||||
|
Operation: new = old * 3
|
||||||
|
Test: divisible by 13
|
||||||
|
If true: throw to monkey 6
|
||||||
|
If false: throw to monkey 2
|
||||||
|
|
||||||
|
Monkey 1:
|
||||||
|
Starting items: 83, 78, 81, 55, 81, 59, 69
|
||||||
|
Operation: new = old + 1
|
||||||
|
Test: divisible by 3
|
||||||
|
If true: throw to monkey 7
|
||||||
|
If false: throw to monkey 4
|
||||||
|
|
||||||
|
Monkey 2:
|
||||||
|
Starting items: 76, 91, 58, 85
|
||||||
|
Operation: new = old * 13
|
||||||
|
Test: divisible by 7
|
||||||
|
If true: throw to monkey 1
|
||||||
|
If false: throw to monkey 4
|
||||||
|
|
||||||
|
Monkey 3:
|
||||||
|
Starting items: 71, 72, 74, 76, 68
|
||||||
|
Operation: new = old * old
|
||||||
|
Test: divisible by 2
|
||||||
|
If true: throw to monkey 6
|
||||||
|
If false: throw to monkey 0
|
||||||
|
|
||||||
|
Monkey 4:
|
||||||
|
Starting items: 98, 85, 84
|
||||||
|
Operation: new = old + 7
|
||||||
|
Test: divisible by 19
|
||||||
|
If true: throw to monkey 5
|
||||||
|
If false: throw to monkey 7
|
||||||
|
|
||||||
|
Monkey 5:
|
||||||
|
Starting items: 78
|
||||||
|
Operation: new = old + 8
|
||||||
|
Test: divisible by 5
|
||||||
|
If true: throw to monkey 3
|
||||||
|
If false: throw to monkey 0
|
||||||
|
|
||||||
|
Monkey 6:
|
||||||
|
Starting items: 86, 70, 60, 88, 88, 78, 74, 83
|
||||||
|
Operation: new = old + 4
|
||||||
|
Test: divisible by 11
|
||||||
|
If true: throw to monkey 1
|
||||||
|
If false: throw to monkey 2
|
||||||
|
|
||||||
|
Monkey 7:
|
||||||
|
Starting items: 81, 58
|
||||||
|
Operation: new = old + 5
|
||||||
|
Test: divisible by 17
|
||||||
|
If true: throw to monkey 3
|
||||||
|
If false: throw to monkey 5
|
143
src/main.rs
143
src/main.rs
|
@ -262,9 +262,152 @@ solutions! {
|
||||||
let cmds = input.lines().map(Cmd::from_str).collect();
|
let cmds = input.lines().map(Cmd::from_str).collect();
|
||||||
Screen::new().draw(cmds).to_string().into()
|
Screen::new().draw(cmds).to_string().into()
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
// day 11 part 1
|
||||||
|
|input| {
|
||||||
|
let monkeys = input.split("\n\n").map(|s| Monkey::from_str(s, false)).collect();
|
||||||
|
run_rounds(monkeys, 20).into()
|
||||||
|
},
|
||||||
|
// day 11 part 2
|
||||||
|
|input| {
|
||||||
|
let monkeys = input.split("\n\n").map(|s| Monkey::from_str(s, true)).collect();
|
||||||
|
run_rounds(monkeys, 10000).into()
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn run_rounds(mut monkeys: Vec<Monkey>, n: usize) -> u64 {
|
||||||
|
let mod_factor: usize = monkeys.iter().map(|m| m.test).product();
|
||||||
|
let mut counts = vec![0; monkeys.len()];
|
||||||
|
for round in 1..=n {
|
||||||
|
let next = run_round(&mut monkeys, mod_factor);
|
||||||
|
counts = next.iter().zip(counts).map(|(x, y)| x + y).collect();
|
||||||
|
if round % 1000 == 0 || round == 20 || round == 1 {}
|
||||||
|
}
|
||||||
|
counts.sort();
|
||||||
|
counts[counts.len() - 1] * counts[counts.len() - 2]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_round(monkeys: &mut Vec<Monkey>, mod_factor: usize) -> Vec<u64> {
|
||||||
|
let mut inspects = vec![];
|
||||||
|
for i in 0..monkeys.len() {
|
||||||
|
let monkey = &mut monkeys[i];
|
||||||
|
let throws = monkey.take_turn(mod_factor);
|
||||||
|
inspects.push(throws.len() as u64);
|
||||||
|
for (to, item) in throws {
|
||||||
|
monkeys[to].items.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inspects
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
enum OpType {
|
||||||
|
Add,
|
||||||
|
Mul,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
struct Op {
|
||||||
|
op_type: OpType,
|
||||||
|
operand: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Op {
|
||||||
|
fn operand(s: &str) -> Option<usize> {
|
||||||
|
match s {
|
||||||
|
"old" => None,
|
||||||
|
_ => Some(s.parse::<usize>().unwrap()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Self {
|
||||||
|
let (op_type, y) = s.split_once(' ').unwrap();
|
||||||
|
Self {
|
||||||
|
op_type: match op_type {
|
||||||
|
"+" => OpType::Add,
|
||||||
|
"*" => OpType::Mul,
|
||||||
|
_ => unreachable!("whoa"),
|
||||||
|
},
|
||||||
|
operand: Self::operand(y),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&self, old: usize) -> usize {
|
||||||
|
let operand = self.operand.unwrap_or(old);
|
||||||
|
match self.op_type {
|
||||||
|
OpType::Add => old.wrapping_add(operand),
|
||||||
|
OpType::Mul => old.wrapping_mul(operand),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
struct Monkey {
|
||||||
|
items: Vec<usize>,
|
||||||
|
operation: Op,
|
||||||
|
test: usize,
|
||||||
|
throw_true: usize,
|
||||||
|
throw_false: usize,
|
||||||
|
part_two: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Monkey {
|
||||||
|
fn from_str(s: &str, part_two: bool) -> Self {
|
||||||
|
let (_, s) = s.split_once('\n').unwrap();
|
||||||
|
let (items, s) = s.split_once('\n').unwrap();
|
||||||
|
let (operation, s) = s.split_once('\n').unwrap();
|
||||||
|
let (test, s) = s.split_once('\n').unwrap();
|
||||||
|
let (throw_true, throw_false) = s.split_once('\n').unwrap();
|
||||||
|
Monkey {
|
||||||
|
items: items
|
||||||
|
.strip_prefix(" Starting items: ")
|
||||||
|
.unwrap()
|
||||||
|
.split(", ")
|
||||||
|
.map(|n| n.parse::<usize>().unwrap())
|
||||||
|
.collect(),
|
||||||
|
operation: Op::from_str(operation.strip_prefix(" Operation: new = old ").unwrap()),
|
||||||
|
test: test
|
||||||
|
.strip_prefix(" Test: divisible by ")
|
||||||
|
.unwrap()
|
||||||
|
.parse::<usize>()
|
||||||
|
.unwrap(),
|
||||||
|
throw_true: throw_true
|
||||||
|
.strip_prefix(" If true: throw to monkey ")
|
||||||
|
.unwrap()
|
||||||
|
.parse::<usize>()
|
||||||
|
.unwrap(),
|
||||||
|
throw_false: throw_false
|
||||||
|
.strip_prefix(" If false: throw to monkey ")
|
||||||
|
.unwrap()
|
||||||
|
.trim()
|
||||||
|
.parse::<usize>()
|
||||||
|
.unwrap(),
|
||||||
|
part_two,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn take_turn(&mut self, mod_factor: usize) -> Vec<(usize, usize)> {
|
||||||
|
self.items
|
||||||
|
.drain(..)
|
||||||
|
.map(|item| {
|
||||||
|
let level = self.operation.apply(item);
|
||||||
|
let level = if self.part_two {
|
||||||
|
level % mod_factor
|
||||||
|
} else {
|
||||||
|
level / 3
|
||||||
|
};
|
||||||
|
if level % self.test == 0 {
|
||||||
|
(self.throw_true, level)
|
||||||
|
} else {
|
||||||
|
(self.throw_false, level)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Screen {
|
struct Screen {
|
||||||
x: isize,
|
x: isize,
|
||||||
cycle: isize,
|
cycle: isize,
|
||||||
|
|
Loading…
Reference in New Issue