summaryrefslogtreecommitdiffstats
path: root/day4/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'day4/__init__.py')
-rw-r--r--day4/__init__.py50
1 files changed, 50 insertions, 0 deletions
diff --git a/day4/__init__.py b/day4/__init__.py
new file mode 100644
index 0000000..677da75
--- /dev/null
+++ b/day4/__init__.py
@@ -0,0 +1,50 @@
1# -*- coding: utf-8 -*-
2from abc import ABC
3from typing import Iterator
4
5from aoc import BaseAssignment
6
7I = tuple[list[int], list[int]]
8T = int
9
10
11class Assignment(BaseAssignment, ABC):
12 def winning_numbers(self, winning: list[int], owned: list[int]) -> set[int]:
13 return set(winning) & set(owned)
14
15 def parse_numbers(self, numbers: str) -> list[int]:
16 return [int(num) for num in numbers.split(" ") if num != ""]
17
18 def parse_item(self, item: str) -> I:
19 _, numbers = item.split(": ")
20 winning, owned = numbers.split(" | ")
21
22 return self.parse_numbers(winning), self.parse_numbers(owned)
23
24
25class AssignmentOne(Assignment):
26 example_result = 13
27
28 def points(self, winning: list[int], owned: list[int]) -> int:
29 overlap = len(self.winning_numbers(winning, owned))
30 return overlap if overlap < 2 else 2 ** (overlap - 1)
31
32 def run(self, input: Iterator[I]) -> T:
33 return sum(self.points(winning, owned) for winning, owned in input)
34
35
36class AssignmentTwo(Assignment):
37 example_result = 30
38
39 def run(self, input: Iterator[I]) -> T:
40 cards = list(input)
41 count = {index: 1 for index, _ in enumerate(cards)}
42
43 for index, (winning, owned) in enumerate(cards):
44 for i in range(len(self.winning_numbers(winning, owned))):
45 winning_index = index + i + 1
46
47 if winning_index in count:
48 count[winning_index] += count[index]
49
50 return sum(count.values())