# gregs-aoc-2021-day-3

unknown
python
3 years ago
2.4 kB
1
Indexable
Never
```import copy

with open("input.txt") as f:
lines = [line.strip() for line in f.readlines()]

class EqualOnesAndZerosError(ValueError):
pass

def find_most_common_bit(lines, position):
ones = 0
zeros = 0
for line in lines:
if line[position] == "1":
ones += 1
elif line[position] == "0":
zeros += 1
else:
raise ValueError(f"line '{line}' has unexpected bit '{bit}'")
if ones > zeros:
return "1"
elif ones < zeros:
return "0"
else:
raise EqualOnesAndZerosError(f"equal 1s and 0s in position {position}")

def find_least_common_bit(lines, position):
most_common_bit = find_most_common_bit(lines, position)
return {"1": "0", "0": "1"}[most_common_bit]

num_bits = len(lines[0])
gamma = "".join([find_most_common_bit(lines, pos) for pos in range(num_bits)])
epsil = "".join([find_least_common_bit(lines, pos) for pos in range(num_bits)])
print(f"gamma={gamma}")
print(f"epsilon={epsil}")
print(f"power consumption={int(gamma, 2) * int(epsil, 2)}")
print()

###

def calculate_oxygen(lines):
lines = copy.copy(lines)
for position in range(num_bits):
try:
most_common_bit = find_most_common_bit(lines, position)
except EqualOnesAndZerosError:
most_common_bit = "1"
remaining_lines = []
for line in lines:
if line[position] == most_common_bit:
remaining_lines.append(line)
lines = remaining_lines
if len(lines) == 1:
return lines[0]
raise Exception("Should've exited by now")

def calculate_co2(lines):
lines = copy.copy(lines)
for position in range(num_bits):
try:
least_common_bit = find_least_common_bit(lines, position)
except EqualOnesAndZerosError:
least_common_bit = "0"
remaining_lines = []
for line in lines:
if line[position] == least_common_bit:
remaining_lines.append(line)
lines = remaining_lines
if len(lines) == 1:
return lines[0]
raise Exception("Should've exited by now")

oxygen_b = calculate_oxygen(lines)
oxygen = int(oxygen_b, 2)
co2_b = calculate_co2(lines)
co2 = int(co2_b, 2)
print(f"oxygen: binary={oxygen_b}, decimal={oxygen}")
print(f"co2: binary={co2_b}, decimal={co2}")
print(f"life support rating: {oxygen*co2}")```