gregs-aoc-2021-day-3

 avatar
unknown
python
4 years ago
2.4 kB
7
Indexable
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}")
Editor is loading...