-
Notifications
You must be signed in to change notification settings - Fork 0
/
day3-2.py
61 lines (38 loc) · 1.49 KB
/
day3-2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from enum import Enum, auto
from typing import List, Dict
class Rating(Enum):
OXYGEN = auto()
CO2 = auto()
def count_values_at_column(arr: List[List[int]], x: int) -> Dict[int, int]:
counter = {0: 0, 1: 0}
for row in arr:
counter[row[x]] += 1
return counter
def get_most_common_value(counter: Dict[int, int]) -> int:
return max(counter, key=counter.get)
def get_least_common_value(counter: Dict[int, int]) -> int:
return min(counter, key=counter.get)
def are_equally_common(counter: Dict[int, int]) -> bool:
return counter[0] == counter[1]
def get_rating(rating: Rating, readings: List[List[int]]) -> str:
arr = readings.copy()
pos = 0
while len(arr) > 1:
counter = count_values_at_column(arr, pos)
if are_equally_common(counter):
value_to_keep = VALUES_TO_KEEP[rating]
else:
value_to_keep = RATING_OPS[rating](counter)
arr = list(filter(lambda x: x[pos] == value_to_keep, arr))
pos += 1
return "".join([str(c) for c in arr[0]])
RATING_OPS = {Rating.OXYGEN: get_most_common_value, Rating.CO2: get_least_common_value}
VALUES_TO_KEEP = {Rating.OXYGEN: 1, Rating.CO2: 0}
if __name__ == "__main__":
bits = []
with open("day3-input.txt") as lines:
for line in lines:
bits.append([int(c) for c in line.strip()])
oxygen_int = int(get_rating(Rating.OXYGEN, bits), base=2)
co2_int = int(get_rating(Rating.CO2, bits), base=2)
print(co2_int * oxygen_int)