58 lines
1.2 KiB
Python
58 lines
1.2 KiB
Python
from lib import *
|
|
|
|
input = read_input(2020, 24)
|
|
|
|
lines = input.splitlines()
|
|
|
|
adj = {"e": (1, 0), "w": (-1, 0), "se": (1, 1), "sw": (0, 1), "ne": (0, -1), "nw": (-1, -1)}
|
|
|
|
|
|
def get_tile(line):
|
|
x = y = 0
|
|
i = 0
|
|
while i < len(line):
|
|
if line[i] in "ew":
|
|
dx, dy = adj[line[i]]
|
|
i += 1
|
|
else:
|
|
dx, dy = adj[line[i : i + 2]]
|
|
i += 2
|
|
x += dx
|
|
y += dy
|
|
return x, y
|
|
|
|
|
|
def get_black():
|
|
black = set()
|
|
for line in lines:
|
|
x, y = get_tile(line)
|
|
if (x, y) in black:
|
|
black.remove((x, y))
|
|
else:
|
|
black.add((x, y))
|
|
return black
|
|
|
|
|
|
print(len(get_black()))
|
|
|
|
|
|
def neighbours(x, y):
|
|
return {(x + dx, y + dy) for dx, dy in adj.values()}
|
|
|
|
|
|
black = get_black()
|
|
for _ in range(100):
|
|
to_update = [(p, q) for x, y in black for p, q in neighbours(x, y) | {(x, y)}]
|
|
flip_white = set()
|
|
flip_black = set()
|
|
for x, y in to_update:
|
|
cnt = len(black & neighbours(x, y))
|
|
alive = (x, y) in black
|
|
if alive and cnt not in (1, 2):
|
|
flip_white.add((x, y))
|
|
elif not alive and cnt == 2:
|
|
flip_black.add((x, y))
|
|
black -= flip_white
|
|
black |= flip_black
|
|
|
|
print(len(black))
|