2021-12-03 16:28:33 +01:00
|
|
|
def load_input() -> list[str]:
|
|
|
|
with open('../.input/day03', 'r') as f:
|
|
|
|
return [line.strip() for line in f.readlines()]
|
|
|
|
|
|
|
|
|
|
|
|
def solve1() -> int:
|
|
|
|
input = load_input()
|
|
|
|
cache = [{"0": 0, "1": 0} for _ in range(len(input[0]))]
|
|
|
|
|
|
|
|
for binary in input:
|
|
|
|
for i, c in enumerate(binary):
|
|
|
|
cache[i][c] += 1
|
|
|
|
|
|
|
|
gamma, epsilon = map(sum, zip(*[
|
|
|
|
(2**i, 0) if c["1"] > c["0"] else (0, 2**i)
|
|
|
|
for i, c in enumerate(reversed(cache))
|
|
|
|
]))
|
|
|
|
return gamma * epsilon
|
|
|
|
|
|
|
|
|
|
|
|
def find_single(input: list[str], reverse: bool = False) -> int:
|
|
|
|
cache = [{"0": 0, "1": 0} for _ in range(len(input[0]))]
|
|
|
|
remaining = input[:]
|
|
|
|
|
|
|
|
for binary in remaining:
|
|
|
|
for i, digit in enumerate(binary):
|
|
|
|
cache[i][digit] += 1
|
|
|
|
|
|
|
|
for i, c in enumerate(cache):
|
|
|
|
if len(remaining) == 1:
|
|
|
|
break
|
|
|
|
|
|
|
|
generator = (entry for entry in remaining)
|
|
|
|
remaining = []
|
|
|
|
winning_digit = ("0" if c["0"] <= c["1"] else "1") if reverse else ("1" if c["1"] >= c["0"] else "0")
|
|
|
|
for binary in generator:
|
|
|
|
if binary[i] == winning_digit:
|
|
|
|
remaining.append(binary)
|
|
|
|
else:
|
|
|
|
for digit, cache_dict in zip(binary, cache):
|
|
|
|
cache_dict[digit] -= 1
|
|
|
|
|
|
|
|
return remaining[0]
|
|
|
|
|
|
|
|
|
|
|
|
def solve2() -> int:
|
|
|
|
input = load_input()
|
|
|
|
oxygen, carbon = input[:], input[:]
|
|
|
|
res_o = sum(2**int(i) for i, x in enumerate(reversed(find_single(oxygen, reverse=False))) if x == "1")
|
|
|
|
res_c = sum(2**int(i) for i, x in enumerate(reversed(find_single(carbon, reverse=True))) if x == "1")
|
|
|
|
return res_o * res_c
|
|
|
|
|
|
|
|
|
2021-12-03 21:15:11 +01:00
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
|
|
|
|
def load_input_np() -> np.ndarray:
|
|
|
|
with open('../.input/day03', 'r') as f:
|
|
|
|
return np.array([list(map(np.int32, list(i.strip()))) for i in f.readlines()])
|
|
|
|
|
|
|
|
|
|
|
|
def solve1_np() -> int:
|
|
|
|
input = load_input_np()
|
|
|
|
binary = (input.mean(axis=0) >= 0.5)
|
|
|
|
invert = np.logical_not(binary)
|
|
|
|
decimalize = 2 ** np.arange(binary.shape[0])[::-1]
|
|
|
|
return sum(binary * decimalize) * sum(invert * decimalize)
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-12-03 16:28:33 +01:00
|
|
|
if __name__ == "__main__":
|
2021-12-03 16:31:30 +01:00
|
|
|
print(solve1()) # 4001724
|
|
|
|
print(solve2()) # 587895
|
2021-12-03 21:15:11 +01:00
|
|
|
|
|
|
|
print(solve1_np()) # 4001724
|