This commit is contained in:
Stefan Harmuth 2022-12-11 07:40:32 +01:00
parent 2be2f11856
commit 36b33242be
3 changed files with 182 additions and 0 deletions

100
day11.py Normal file
View File

@ -0,0 +1,100 @@
from collections import defaultdict
from math import lcm
from tools.aoc import AOCDay
from typing import Any
class Monkey:
def __init__(self, monkey_id: int):
self.monkey_id = monkey_id
self.items = []
self.operation = None
self.test = None
self.action_true = None
self.action_false = None
def turn(self, part2: bool = False):
for _ in range(len(self.items)):
item = self.items.pop(0)
op, right = self.operation
if op == "+":
item += int(right)
elif right == "old":
item *= item
else:
item *= int(right)
if not part2:
item //= 3
if item % self.test == 0:
yield item, self.action_true
else:
yield item, self.action_false
class Day(AOCDay):
inputs = [
[
(10605, "input11_test"),
(98280, "input11"),
],
[
(2713310158, "input11_test"),
(17673687232, "input11"),
]
]
def get_monkeys(self) -> list:
monkeys = {}
current_monkey = None
for line in self.getInput():
if not line:
continue
if line.startswith("Monkey"):
current_monkey = Monkey(int(line[:-1].split(" ")[1]))
monkeys[current_monkey.monkey_id] = current_monkey
elif line.startswith(" Starting items:"):
current_monkey.items = list(map(int, line.split(": ")[1].split(", ")))
elif line.startswith(" Operation"):
current_monkey.operation = line.split(": ")[1].split(" = ")[1].split(" ")[1:]
elif line.startswith(" Test:"):
current_monkey.test = int(line.split(" ")[-1])
elif line.startswith(" If true:"):
current_monkey.action_true = int(line.split(" ")[-1])
elif line.startswith(" If false:"):
current_monkey.action_false = int(line.split(" ")[-1])
else:
print("Don't know how to parse '", line, "'")
return [monkeys[x] for x in sorted(monkeys)]
def get_monkey_business(self, amount: int = 20, part2: bool = False) -> int:
monkeys = self.get_monkeys()
monkey_inspects = defaultdict(int)
modder = lcm(*[m.test for m in monkeys])
for _ in range(amount):
for monkey in monkeys:
for item, target in monkey.turn(part2):
monkey_inspects[monkey.monkey_id] += 1
if part2:
monkeys[target].items.append(item % modder)
else:
monkeys[target].items.append(item)
f = sorted(monkey_inspects.values())[-2:]
return f[0] * f[1]
def part1(self) -> Any:
return self.get_monkey_business(20, False)
def part2(self) -> Any:
return self.get_monkey_business(10_000, True)
if __name__ == '__main__':
day = Day(2022, 11)
day.run(verbose=True)

55
inputs/input11 Normal file
View File

@ -0,0 +1,55 @@
Monkey 0:
Starting items: 56, 52, 58, 96, 70, 75, 72
Operation: new = old * 17
Test: divisible by 11
If true: throw to monkey 2
If false: throw to monkey 3
Monkey 1:
Starting items: 75, 58, 86, 80, 55, 81
Operation: new = old + 7
Test: divisible by 3
If true: throw to monkey 6
If false: throw to monkey 5
Monkey 2:
Starting items: 73, 68, 73, 90
Operation: new = old * old
Test: divisible by 5
If true: throw to monkey 1
If false: throw to monkey 7
Monkey 3:
Starting items: 72, 89, 55, 51, 59
Operation: new = old + 1
Test: divisible by 7
If true: throw to monkey 2
If false: throw to monkey 7
Monkey 4:
Starting items: 76, 76, 91
Operation: new = old * 3
Test: divisible by 19
If true: throw to monkey 0
If false: throw to monkey 3
Monkey 5:
Starting items: 88
Operation: new = old + 4
Test: divisible by 2
If true: throw to monkey 6
If false: throw to monkey 4
Monkey 6:
Starting items: 64, 63, 56, 50, 77, 55, 55, 86
Operation: new = old + 8
Test: divisible by 13
If true: throw to monkey 4
If false: throw to monkey 0
Monkey 7:
Starting items: 79, 58
Operation: new = old + 6
Test: divisible by 17
If true: throw to monkey 1
If false: throw to monkey 5

27
inputs/input11_test 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