advent-of-code/2022/python/day11.py

110 lines
3.0 KiB
Python
Raw Permalink Normal View History

2022-12-11 05:44:32 +00:00
import shared
2022-12-11 06:28:52 +00:00
import operator
2022-12-11 05:56:44 +00:00
import math
2022-12-11 06:28:52 +00:00
2022-12-11 05:44:32 +00:00
from dataclasses import dataclass
from typing import Callable
@dataclass
class Monkey:
number: int
items: list
div: int
t: int
f: int
by: int
op: operator
inspect_count: int = 0
def load_monkeys(lines):
monkeys = []
count = 0
for line in lines:
if line.lstrip().startswith("Starting"):
items = list(map(int, line.split(": ")[-1].split(",")))
elif line.lstrip().startswith("Operation"):
op = line.split(": ")[-1]
try:
by = int(line.split(" ")[-1])
except ValueError:
2022-12-12 07:41:14 +00:00
by = None # know None means by self
if "*" in op:
2022-12-11 05:44:32 +00:00
operand = operator.mul
2022-12-12 07:41:14 +00:00
elif "+" in op:
2022-12-11 05:44:32 +00:00
operand = operator.add
elif line.lstrip().startswith("Test"):
div = int(line.split(" ")[-1])
elif line.lstrip().startswith("If true"):
true = int(line.split(" ")[-1])
elif line.lstrip().startswith("If false"):
false = int(line.split(" ")[-1])
monkey = Monkey(
2022-12-12 07:41:14 +00:00
number=count, items=items, op=operand, by=by, div=div, t=true, f=false
)
2022-12-11 05:44:32 +00:00
monkeys.append(monkey)
2022-12-12 07:41:14 +00:00
count += 1
2022-12-11 05:56:44 +00:00
lcm = math.lcm(*[m.div for m in monkeys])
return monkeys, lcm
2022-12-11 05:44:32 +00:00
2022-12-12 07:41:14 +00:00
2022-12-11 05:44:32 +00:00
def part1(lines):
2022-12-11 05:56:44 +00:00
monkeys, _ = load_monkeys(lines)
2022-12-11 05:44:32 +00:00
2022-12-11 05:56:44 +00:00
for current_round in range(20):
2022-12-11 05:44:32 +00:00
for monkey in monkeys:
for item in monkey.items:
monkey.inspect_count += 1
if monkey.by is None:
# Self
item = monkey.op(item, item)
else:
item = monkey.op(item, monkey.by)
item = item // 3
if item % monkey.div == 0:
to = monkey.t
else:
to = monkey.f
monkeys[to].items.append(item)
monkey.items = []
counts = list(sorted([monkey.inspect_count for monkey in monkeys]))
total = counts[-1] * counts[-2]
print(total)
2022-12-12 07:41:14 +00:00
2022-12-11 05:44:32 +00:00
def part2(lines):
2022-12-11 05:56:44 +00:00
monkeys, lcm = load_monkeys(lines)
2022-12-11 05:44:32 +00:00
2022-12-11 05:56:44 +00:00
for current_round in range(10000):
2022-12-11 05:44:32 +00:00
for monkey in monkeys:
for item in monkey.items:
monkey.inspect_count += 1
if monkey.by is None:
# Self
item = monkey.op(item, item)
else:
item = monkey.op(item, monkey.by)
2022-12-11 05:56:44 +00:00
item = item % lcm
2022-12-11 05:44:32 +00:00
if item % monkey.div == 0:
to = monkey.t
else:
to = monkey.f
monkeys[to].items.append(item)
monkey.items = []
counts = list(sorted([monkey.inspect_count for monkey in monkeys]))
total = counts[-1] * counts[-2]
print(total)
def main():
rows = [row for row in shared.load(11)]
2022-12-11 05:59:13 +00:00
part1(rows)
2022-12-11 05:44:32 +00:00
part2(rows)
if __name__ == "__main__":
main()