-
Notifications
You must be signed in to change notification settings - Fork 0
/
aoc_3.py
61 lines (48 loc) · 1.79 KB
/
aoc_3.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 functools import reduce
def load_diagnostics(filename):
file = open(filename, "r")
try:
lines = file.readlines()
return [s.strip() for s in lines]
finally:
file.close()
def count_bits_values(values, posn):
result = [0, 0]
for value in values:
if (value[posn] == '0'):
result[0] = result[0] + 1
else:
result[1] = result[1] + 1
return result
def part_a(filename):
diagnostics = load_diagnostics(filename)
diagnostic_bits = map(lambda value: [1 if x == '1' else -1 for x in value], diagnostics)
bit_count = len(diagnostics[0])
init = [0] * bit_count
result = reduce(lambda accuml, entry: [acc + ent for acc, ent in zip(accuml, entry)], diagnostic_bits, init)
# 1 if most commonly 1, else 0
gamma_str = "".join(["1" if x > 0 else "0" for x in result])
gamma = int(gamma_str, 2)
# 0 if most commonly 1, else 1
epsilon_str = "".join(["0" if x > 0 else "1" for x in result])
epsilon = int(epsilon_str, 2)
return gamma * epsilon
def part_b(filename):
diagnostics = load_diagnostics(filename)
remaining = diagnostics
posn = 0
while len(remaining) > 1:
bit_counts = count_bits_values(remaining, posn)
mask = "0" if bit_counts[0] > bit_counts[1] else "1"
remaining = list(filter((lambda x: x[posn] == mask), remaining))
posn = posn + 1
oxygen_rating = int(remaining[0], 2)
remaining = diagnostics
posn = 0
while len(remaining) > 1:
bit_counts = count_bits_values(remaining, posn)
mask = "0" if bit_counts[0] <= bit_counts[1] else "1"
remaining = list(filter((lambda x: x[posn] == mask), remaining))
posn = posn + 1
co2_rating = int(remaining[0], 2)
return oxygen_rating * co2_rating