Skip to content

Instantly share code, notes, and snippets.

@rendyanthony
Last active December 24, 2020 07:27
Show Gist options
  • Save rendyanthony/451fc31d2f4e4935c4dc1a5252b4e17d to your computer and use it in GitHub Desktop.
Save rendyanthony/451fc31d2f4e4935c4dc1a5252b4e17d to your computer and use it in GitHub Desktop.
Advent of Code 2020 Day 24
from io import StringIO
def parse(line):
fp = StringIO(line)
while True:
d1 = fp.read(1)
if not d1:
break
if d1 in ('s', 'n'):
d2 = fp.read(1)
if d2 in ('e', 'w'):
yield d1+d2
else:
yield d1
if d2:
yield d2
else:
yield d1
def get_pos(line):
X, Y = 0, 1
pos = [0, 0]
steps = []
for direction in parse(line):
if direction == 'e':
pos = pos[X] - 2, pos[Y]
if direction == 'w':
pos = pos[X] + 2, pos[Y]
if direction == 'se':
pos = pos[X] - 1, pos[Y] + 1
if direction == 'sw':
pos = pos[X] + 1, pos[Y] + 1
if direction == 'nw':
pos = pos[X] + 1, pos[Y] - 1
if direction == 'ne':
pos = pos[X] - 1, pos[Y] - 1
steps.append(tuple(pos))
return tuple(pos), set(steps)
BLACK = 0x01
WHITE = 0x00
def flip(tile):
return BLACK if (tile == WHITE) else WHITE
## Part 1
touched = {}
with open("input_24") as fp:
for line in fp:
pos, _ = get_pos(line)
touched[pos] = flip(touched.get(pos, WHITE))
print(list(touched.values()).count(BLACK))
## Part 2
def adjacent_flip(tiles, pos):
color = tiles[pos]
px, py = pos
n = 0
for dx, dy in [(1, -1), (2, 0), (+1, +1), (-1, +1), (-2, 0), (-1, -1)]:
if tiles.get((px+dx, py+dy), WHITE) == BLACK:
n += 1
if n > 2: break # Minor optimization
if (color == WHITE and n == 2) or (color == BLACK and (n == 0 or n > 2)):
return True
return False
def fill(tiles, subset=None):
if not subset:
subset = list(tiles.keys())
for px, py in subset:
for dx, dy in [(1, -1), (2, 0), (+1, +1), (-1, +1), (-2, 0), (-1, -1)]:
if (px+dx, py+dy) not in tiles:
tiles[(px+dx, py+dy)] = WHITE
tiles = {}
for line in open("input_24"):
pos, steps = get_pos(line)
for step in steps:
tiles[step] = tiles.get(step, WHITE)
tiles[pos] = flip(tiles.get(pos, WHITE))
fill(tiles)
for i in range(100):
to_flip = []
for pos in tiles.keys():
if adjacent_flip(tiles, pos):
to_flip.append(pos)
for pos in to_flip:
if tiles[pos] == BLACK:
tiles[pos] = WHITE
else:
tiles[pos] = BLACK
fill(tiles, to_flip)
# print("Day:", i+1, list(tiles.values()).count(BLACK))
print(list(tiles.values()).count(BLACK))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment