Initial commit with days 1, 2, and 3
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
70
day03/day03.py
Executable file
70
day03/day03.py
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/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)
|
||||
Reference in New Issue
Block a user