94 lines
2.3 KiB
Python
94 lines
2.3 KiB
Python
from collections import Counter
|
|
import time
|
|
# import operator
|
|
|
|
|
|
def read_moves():
|
|
with open('day24/input') as reader:
|
|
return reader.read().splitlines()
|
|
|
|
|
|
def split_move(move):
|
|
split_moves = []
|
|
cur = ''
|
|
for c in move:
|
|
if cur == '' and c in ('e', 'w'):
|
|
split_moves.append(c)
|
|
elif c in ('n', 's'):
|
|
cur = c
|
|
else:
|
|
split_moves.append(cur + c)
|
|
cur = ''
|
|
return split_moves
|
|
|
|
|
|
move_set = {'e': (2, 0), 'w': (-2, 0), 'ne': (1, 1), 'nw': (-1, 1), 'se': (1, -1), 'sw': (-1, -1)}
|
|
|
|
|
|
def add_move(a, b):
|
|
return a[0]+b[0], a[1]+b[1]
|
|
# return tuple(map(sum, zip(a, b)))
|
|
# return tuple(map(operator.add, a, b))
|
|
|
|
|
|
def reduce_moves(move):
|
|
tile = (0, 0)
|
|
for m in move:
|
|
tile = add_move(tile, move_set[m])
|
|
return tile
|
|
|
|
|
|
moves = read_moves()
|
|
split_moves = map(split_move, moves)
|
|
reduced_moves = map(reduce_moves, split_moves)
|
|
|
|
tile_count = Counter(reduced_moves)
|
|
|
|
black_tiles = [tile for tile, amount in tile_count.items() if amount % 2 == 1]
|
|
|
|
print(len(black_tiles))
|
|
|
|
|
|
# part2
|
|
def black_needs_to_turn_white(adjacents, current_black):
|
|
black_adjacent = adjacents.intersection(current_black)
|
|
return len(black_adjacent) == 0 or len(black_adjacent) > 2
|
|
|
|
|
|
def white_needs_to_turn_black(white, current_black):
|
|
adjacent_to_white = get_adjacents(white)
|
|
blacks_adjacent_to_white = adjacent_to_white.intersection(current_black)
|
|
return len(blacks_adjacent_to_white) == 2
|
|
|
|
|
|
def get_adjacents(current):
|
|
adjacents = set()
|
|
for m in move_set.values():
|
|
adjacents.add(add_move(current, m))
|
|
return adjacents
|
|
|
|
|
|
start = time.time()
|
|
previous_black = set(black_tiles)
|
|
for i in range(100):
|
|
black_next = set()
|
|
already_checked = set(previous_black)
|
|
|
|
for black in previous_black:
|
|
adjacents = get_adjacents(black)
|
|
if not black_needs_to_turn_white(adjacents, previous_black):
|
|
black_next.add(black)
|
|
|
|
for a in adjacents:
|
|
if a not in already_checked:
|
|
already_checked.add(a)
|
|
if white_needs_to_turn_black(a, previous_black):
|
|
black_next.add(a)
|
|
|
|
if i == 99:
|
|
print("Day {}: {}".format(str(i+1), len(black_next)))
|
|
previous_black = black_next
|
|
|
|
end = time.time()
|
|
print(end - start)
|