Files
adventofcode-2021/day03/day03.py
2021-12-03 12:36:35 -08:00

71 lines
2.1 KiB
Python
Executable File

#!/usr/bin/env python3
import copy
import sys
from typing import Sequence
def part1(lines: Sequence[int], bits=12):
gamma = 0
epsilon = 0
for bit in range(bits):
mask = 1 << (bits - bit - 1)
ones = 0
for line in lines:
if mask & line:
ones += 1
zeroes = len(lines) - ones
if ones > zeroes:
gamma |= mask
else:
epsilon |= mask
# Fun thing - epsilon rate is just the inversion of the gamma rate.
# However, python doesn't seem to support signed inversion so we just calculate it above. boo
print(f"gamma: {gamma} {bin(gamma)}")
print(f"epsilon: {epsilon} {bin(epsilon)}")
print(f"product: {gamma * epsilon}")
def part2(lines: Sequence[int], bits=12):
oxygen = copy.deepcopy(lines)
carbon = copy.deepcopy(lines)
for bit in range(bits):
# Find the most common bit
if len(oxygen) > 1:
mask = 1 << (bits - bit - 1)
ones = 0
for line in oxygen:
if mask & line:
ones += 1
zeroes = len(oxygen) - ones
if ones >= zeroes:
# Filter out oxygen numbers that don't have a 1 in this position
oxygen = [line for line in oxygen if line & mask]
else:
oxygen = [line for line in oxygen if not (line & mask)]
# Now do this on the carbon array
if len(carbon) > 1:
ones = 0
for line in carbon:
if mask & line:
ones += 1
zeroes = len(carbon) - ones
if ones >= zeroes:
# Keep the *least* common
carbon = [line for line in carbon if not (line & mask)]
else:
carbon = [line for line in carbon if line & mask]
oxygen, = oxygen
carbon, = carbon
print(f"Oxygen: {oxygen}")
print(f"Carbon: {carbon}")
print(f"Product: {oxygen * carbon}")
lines = [int(line, 2) for line in sys.stdin]
print("Part 1")
part1(lines)
print("Part 2")
part2(lines)