summaryrefslogtreecommitdiffstats
path: root/day11/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'day11/__init__.py')
-rw-r--r--day11/__init__.py100
1 files changed, 100 insertions, 0 deletions
diff --git a/day11/__init__.py b/day11/__init__.py
new file mode 100644
index 0000000..7ed8fbc
--- /dev/null
+++ b/day11/__init__.py
@@ -0,0 +1,100 @@
1# -*- coding: utf-8 -*-
2import dataclasses
3from abc import ABC
4from typing import List, Iterator, Any, Tuple
5
6from aoc import BaseAssignment
7
8
9@dataclasses.dataclass
10class Monkey:
11 items: List[int]
12 operation: List[str]
13 test_divisible: int
14 test_true: int
15 test_false: int
16 worry_divider: int = 1
17
18 inspections: int = 0
19
20 @classmethod
21 def from_input(cls, lines: List[str], worry_divider: int):
22 _, items = lines[1].split(":")
23
24 return cls(
25 items=[int(item) for item in items.split(",")],
26 operation=lines[2].split(" ")[-2:],
27 test_divisible=int(lines[3].split(" ")[-1]),
28 test_true=int(lines[4].split(" ")[-1]),
29 test_false=int(lines[5].split(" ")[-1]),
30 worry_divider=worry_divider,
31 )
32
33 def new_worry_factor(self, item: int, worry_factor=1) -> int:
34 operator, value = self.operation
35 value = item if value == "old" else int(value)
36
37 match operator:
38 case "+":
39 return item + value
40 case "*":
41 return item * value
42
43 def throw_to(self, new_worry_factor: int) -> int:
44 if new_worry_factor % self.test_divisible == 0:
45 return self.test_true
46 return self.test_false
47
48 def inspect_items(self) -> Iterator[Tuple[int, int]]:
49 for item in self.items:
50 self.inspections += 1
51 new_worry_factor = self.new_worry_factor(item) // self.worry_divider
52 yield new_worry_factor, self.throw_to(new_worry_factor)
53
54 self.items = []
55
56
57class Assignment(BaseAssignment, ABC):
58 def parse_monkeys(self, input: Iterator[str], worry_divider: int):
59 monkeys = []
60 monkey = []
61 for line in input:
62 if line == "":
63 monkeys.append(Monkey.from_input(monkey, worry_divider))
64 monkey = []
65 continue
66
67 monkey.append(line)
68
69 if len(monkey) != 0:
70 monkeys.append(Monkey.from_input(monkey, worry_divider))
71
72 return monkeys
73
74 def calculate_monkey_business(
75 self, input: Iterator[str], rounds: int, worry_divider: int = 1
76 ):
77 monkeys = self.parse_monkeys(input, worry_divider)
78
79 for _ in range(rounds):
80 for monkey in monkeys:
81 for item, other_monkey in monkey.inspect_items():
82 monkeys[other_monkey].items.append(item)
83
84 a, b = sorted([monkey.inspections for monkey in monkeys])[-2:]
85
86 return a * b
87
88
89class AssignmentOne(Assignment):
90 example_result = 10605
91
92 def run(self, input: Iterator) -> Any:
93 return self.calculate_monkey_business(input, 20, 3)
94
95
96class AssignmentTwo(Assignment):
97 example_result = 2713310158
98
99 def run(self, input: Iterator) -> Any:
100 return self.calculate_monkey_business(input, 10000)