day 11
This commit is contained in:
parent
40c08275cc
commit
12d1c427cf
122
src/day11.py
Normal file
122
src/day11.py
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import textwrap
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from functools import reduce
|
||||||
|
from math import lcm
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from cpl_core.console import Console
|
||||||
|
from cpl_core.utils import String
|
||||||
|
from cpl_query.enumerable import Enumerable
|
||||||
|
from cpl_query.extension import List
|
||||||
|
from cpl_core.pipes import *
|
||||||
|
|
||||||
|
from aoc.aoc import get_input
|
||||||
|
|
||||||
|
# global vars
|
||||||
|
day = 11
|
||||||
|
aoc_input = get_input(2022, day)
|
||||||
|
aoc_input1 = """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
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class Monkey:
|
||||||
|
|
||||||
|
def __init__(self, m: List[str]):
|
||||||
|
self.items = List(int)
|
||||||
|
self.operation = ''
|
||||||
|
self.test = ''
|
||||||
|
self.test_true_action = None
|
||||||
|
self.test_false_action = None
|
||||||
|
self.inspects = 0
|
||||||
|
|
||||||
|
for x in m:
|
||||||
|
x = str(x).replace(' ', '')
|
||||||
|
if ':' not in x:
|
||||||
|
continue
|
||||||
|
|
||||||
|
atr, value = x.split(':')
|
||||||
|
match atr:
|
||||||
|
case 'Startingitems':
|
||||||
|
for v in value.split(','):
|
||||||
|
self.items.append(int(v))
|
||||||
|
case 'Operation':
|
||||||
|
self.operation = value
|
||||||
|
case 'Test':
|
||||||
|
self.test = value
|
||||||
|
self.divisor = int(self.test.split('divisibleby')[1])
|
||||||
|
case 'Iftrue':
|
||||||
|
self.test_true_action = value
|
||||||
|
case 'Iffalse':
|
||||||
|
self.test_false_action = value
|
||||||
|
|
||||||
|
self.initial_items = self.items.copy()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f'<Monkey {self.inspects} {self.items}>'
|
||||||
|
|
||||||
|
def do_work(self, monkeys: List['Monkey'], modulus, part2=False):
|
||||||
|
remove = []
|
||||||
|
for old in self.items:
|
||||||
|
self.inspects += 1
|
||||||
|
if part2:
|
||||||
|
new = int(eval(self.operation.split('=')[1]))
|
||||||
|
else:
|
||||||
|
new = int(eval(self.operation.split('=')[1]) / 3)
|
||||||
|
new %= modulus
|
||||||
|
|
||||||
|
divisible = new % int(self.test.split('divisibleby')[1]) == 0
|
||||||
|
|
||||||
|
throw_to = monkeys.element_at(int((self.test_true_action if divisible else self.test_false_action).split('throwtomonkey')[1]))
|
||||||
|
|
||||||
|
throw_to.items.append(new)
|
||||||
|
remove.append(old)
|
||||||
|
|
||||||
|
for r in remove:
|
||||||
|
self.items.remove(r)
|
||||||
|
|
||||||
|
|
||||||
|
def main(part2=False):
|
||||||
|
monkeys = List(str, aoc_input.splitlines()) \
|
||||||
|
.select(lambda x: x if not str(x).startswith('Monkey') else None).where(lambda x: x is not None) \
|
||||||
|
.split(lambda x: '') \
|
||||||
|
.select(lambda monkey: Monkey(monkey))
|
||||||
|
|
||||||
|
mod = lcm(*monkeys.select(lambda x: x.divisor))
|
||||||
|
for i in range(0, 10000 if part2 else 20):
|
||||||
|
for m in monkeys:
|
||||||
|
m.do_work(monkeys, mod, part2)
|
||||||
|
|
||||||
|
Console.write_line(reduce((lambda x, y: x * y), monkeys.order_by_descending(lambda x: x.inspects).take(2).select(lambda x: x.inspects)))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
Console.write_line(f'Advent of code day {day}')
|
||||||
|
main()
|
||||||
|
main(True)
|
||||||
|
Console.write_line()
|
Loading…
Reference in New Issue
Block a user