summaryrefslogtreecommitdiffstats
path: root/day3/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'day3/__init__.py')
-rw-r--r--day3/__init__.py96
1 files changed, 96 insertions, 0 deletions
diff --git a/day3/__init__.py b/day3/__init__.py
new file mode 100644
index 0000000..29f4ab3
--- /dev/null
+++ b/day3/__init__.py
@@ -0,0 +1,96 @@
1from collections import Counter
2from copy import copy
3from dataclasses import dataclass
4from typing import Iterator, List
5
6from aoc import BaseAssignment
7
8class Assignment(BaseAssignment):
9 def read_input(self, example = False) -> List[str]:
10 return list(super().read_input(example))
11
12 @staticmethod
13 def flip(bits: str) -> str:
14 return bin(~int(bits, 2) + (1 << len(bits))).strip('0b')
15
16
17class AssignmentOne(Assignment):
18 example_result = 198
19 @staticmethod
20 def convert(input: List[str]) -> List[List[str]]:
21 items = []
22 for item in input:
23 for index, char in enumerate([char for char in item]):
24 try:
25 items[index].append(char)
26 except IndexError:
27 items.append([char])
28
29 return items
30
31 @staticmethod
32 def gamma_rate(input: List[str]) -> str:
33 converted = AssignmentOne.convert(input)
34 return ''.join([
35 Counter(i).most_common(1)[0][0]
36 for i
37 in converted
38 ])
39
40 @staticmethod
41 def epsilon_rate(input: List[str]) -> str:
42 return Assignment.flip(AssignmentOne.gamma_rate(input))
43
44 def run(self, input: List[str]) -> int:
45 return int(self.gamma_rate(input), 2) * int(self.epsilon_rate(input), 2)
46
47
48class AssignmentTwo(Assignment):
49 example_result = 230
50
51 @staticmethod
52 def oxygen_generator_rating(input: List[str]):
53 bit_length = len(input[0])
54
55 modified_input = copy(input)
56 bits = ''
57 for i in range(bit_length):
58 count = Counter([_[i] for _ in modified_input]).most_common(2)
59
60 most_used = count[0]
61 most_used_count = most_used[1]
62 least_used = count[-1]
63 least_used_count = least_used[1]
64
65 bit = '1' if most_used_count == least_used_count else most_used[0]
66
67 bits += bit
68 modified_input = list(filter(lambda _: _[i] == bit, modified_input))
69
70 return bits
71
72 @staticmethod
73 def co2_scrubbing_rating(input: List[str]):
74 bit_length = len(input[0])
75
76 modified_input = copy(input)
77 for i in range(bit_length):
78 if len(modified_input) == 1:
79 return modified_input[0]
80
81 count = Counter([_[i] for _ in modified_input]).most_common(2)
82
83 most_used = count[0]
84 most_used_count = most_used[1]
85 least_used = count[-1]
86 least_used_count = least_used[1]
87
88 bit = '0' if most_used_count == least_used_count else least_used[0]
89
90 modified_input = list(filter(lambda _: _[i] == bit, modified_input))
91
92
93 def run(self, input: List[str]) -> int:
94 return int(AssignmentTwo.oxygen_generator_rating(input), 2) \
95 * int(AssignmentTwo.co2_scrubbing_rating(input), 2)
96