summaryrefslogtreecommitdiffstats
path: root/day8/__init__.py
diff options
context:
space:
mode:
authorGravatar Tom van der Lee <tom@vanderlee.io>2021-12-08 11:27:20 +0100
committerGravatar Tom van der Lee <tom@vanderlee.io>2021-12-08 11:29:20 +0100
commitb6751db2cd765d53d36a63d6a5e7c4c1b438e11a (patch)
tree7162ed2d161fea64370f2f445e40da039b60c861 /day8/__init__.py
parentd22c1b117eda357267f2c93193d23d32779cbd69 (diff)
download2021-b6751db2cd765d53d36a63d6a5e7c4c1b438e11a.tar.gz
2021-b6751db2cd765d53d36a63d6a5e7c4c1b438e11a.tar.bz2
2021-b6751db2cd765d53d36a63d6a5e7c4c1b438e11a.zip
Day 8
Diffstat (limited to 'day8/__init__.py')
-rw-r--r--day8/__init__.py112
1 files changed, 112 insertions, 0 deletions
diff --git a/day8/__init__.py b/day8/__init__.py
new file mode 100644
index 0000000..4a72c1f
--- /dev/null
+++ b/day8/__init__.py
@@ -0,0 +1,112 @@
1from collections import Counter
2from copy import copy
3from typing import List, Tuple, Dict, FrozenSet
4
5from aoc import BaseAssignment
6
7class UnknownException(Exception):
8 pass
9
10Item = FrozenSet[str]
11Information = Tuple[List[Item], List[Item]]
12
13class Assignment(BaseAssignment):
14 def parse_item(self, item: str) -> Tuple[List[Item], List[Item]]:
15 input, output = item.split('|')
16
17 return (
18 [frozenset(i.strip()) for i in input.split(' ') if i != ''],
19 [frozenset(i.strip()) for i in output.split(' ') if i != '']
20 )
21
22 def read_input(self, example = False) -> List[Tuple[List[str], List[str]]]:
23 return list(super().read_input(example))
24
25 @staticmethod
26 def calc_digit(item: Item, known_numbers: Dict[int, Item] = None) -> int:
27 if known_numbers is None:
28 known_numbers = {}
29
30 match len(item):
31 case 2:
32 return 1
33 case 3:
34 return 7
35 case 4:
36 return 4
37 case 5:
38 if 1 in known_numbers and item.issuperset(known_numbers[1]):
39 return 3
40 elif 4 in known_numbers and len(item | known_numbers[4]) == 7:
41 return 2
42 else:
43 return 5
44 case 6:
45 if 1 in known_numbers and not item.issuperset(known_numbers[1]):
46 return 6
47 elif 3 in known_numbers and item.issuperset(known_numbers[3]):
48 return 9
49 else:
50 return 0
51 case 7:
52 return 8
53 case _:
54 raise UnknownException()
55
56 @staticmethod
57 def unique_filter(item: Item) -> bool:
58 try:
59 return Assignment.calc_digit(item) in [1, 4, 7, 8]
60 except UnknownException:
61 return False
62
63
64class AssignmentOne(Assignment):
65 example_result = 26
66
67 def run(self, input: List[Information]) -> int:
68 return sum([
69 len(list(filter(Assignment.unique_filter, output)))
70 for _, output in input
71 ])
72
73
74class AssignmentTwo(Assignment):
75 example_result = 61229
76
77 @staticmethod
78 def find_all_numbers(items: List[Item]) -> Dict[int, Item]:
79 known_numbers = {
80 Assignment.calc_digit(item): item
81 for item in filter(Assignment.unique_filter, items)
82 }
83
84 unknown_numbers = {
85 item
86 for item
87 in filter(
88 lambda item: item not in known_numbers.values(),
89 items
90 )
91 }
92
93 while len(unknown_numbers) > 0:
94 for number in copy(unknown_numbers):
95 try:
96 nr = Assignment.calc_digit(number, known_numbers)
97 known_numbers[nr] = number
98 unknown_numbers.remove(number)
99 except UnknownException:
100 continue
101
102 return known_numbers
103
104 def run(self, input: List[Information]) -> int:
105 return sum([
106 sum(
107 self.calc_digit(item, self.find_all_numbers(input + output))
108 * (10 ** (len(output) - index - 1))
109 for index, item in enumerate(output)
110 )
111 for input, output in input
112 ])