You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.1 KiB
Python
84 lines
2.1 KiB
Python
3 years ago
|
"""Solution for 2020/24"""
|
||
|
|
||
|
from collections import defaultdict
|
||
|
|
||
|
instructions = []
|
||
|
with open('input', 'r') as f:
|
||
|
for line in f.readlines():
|
||
|
line = line.strip()
|
||
|
i = 0
|
||
|
instruction = []
|
||
|
while i < len(line):
|
||
|
if line[i] in ['w', 'e']:
|
||
|
instruction.append(line[i])
|
||
|
else:
|
||
|
instruction.append(line[i:i+2])
|
||
|
i += 1
|
||
|
i += 1
|
||
|
instructions.append(instruction)
|
||
|
|
||
|
|
||
|
print(instructions)
|
||
|
|
||
|
MOVEMENTS = {
|
||
|
'e': (1, 0),
|
||
|
'w': (-1, 0),
|
||
|
'ne': (0, 1),
|
||
|
'sw': (0, -1),
|
||
|
'nw': (-1, 1),
|
||
|
'se': (1, -1),
|
||
|
}
|
||
|
|
||
|
MOVES = 100
|
||
|
|
||
|
|
||
|
def main():
|
||
|
flipped_tiles = defaultdict(int)
|
||
|
|
||
|
for instruction in instructions:
|
||
|
coord = parse_instruction(instruction)
|
||
|
flipped_tiles[coord] += 1
|
||
|
|
||
|
print(''.join(instruction), coord)
|
||
|
blacks = set([x[0] for x in flipped_tiles.items() if x[1] % 2 == 1])
|
||
|
|
||
|
for day in range(MOVES):
|
||
|
new_blacks = set()
|
||
|
bbox = get_bbox(blacks)
|
||
|
for x in range(bbox[0] - 1, bbox[2] + 2):
|
||
|
for y in range(bbox[1] - 1, bbox[3] + 2):
|
||
|
coord = (x, y)
|
||
|
neighbors = get_neighbors(coord)
|
||
|
adj_blacks = len([x for x in neighbors if x in blacks])
|
||
|
is_black = coord in blacks
|
||
|
if is_black and adj_blacks in [1, 2]:
|
||
|
new_blacks.add(coord)
|
||
|
elif not is_black and adj_blacks == 2:
|
||
|
new_blacks.add(coord)
|
||
|
blacks = new_blacks
|
||
|
print(f'Day {day+1:>3}: {len(blacks)}')
|
||
|
|
||
|
|
||
|
def parse_instruction(instruction):
|
||
|
coord = (0, 0)
|
||
|
for move in instruction:
|
||
|
dx, dy = MOVEMENTS[move]
|
||
|
coord = (coord[0] + dx, coord[1] + dy)
|
||
|
return coord
|
||
|
|
||
|
|
||
|
def get_bbox(coords):
|
||
|
x_coords = list(map(lambda coord: coord[0], coords))
|
||
|
y_coords = list(map(lambda coord: coord[1], coords))
|
||
|
return min(x_coords), min(y_coords), max(x_coords), max(y_coords)
|
||
|
|
||
|
|
||
|
def get_neighbors(coord):
|
||
|
neigh = []
|
||
|
for dx, dy in MOVEMENTS.values():
|
||
|
neigh.append((coord[0] + dx, coord[1] + dy))
|
||
|
return neigh
|
||
|
|
||
|
|
||
|
main()
|