Created
January 5, 2021 04:52
-
-
Save napisani/247790cdd76f72de34b29d4ac6950874 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import List | |
all_tiles = dict() | |
vector_map = { | |
'ne': (1, 1), | |
'nw': (-1, 1), | |
'e': (2, 0), | |
'w': (-2, 0), | |
'sw': (-1, -1), | |
'se': (1, -1) | |
} | |
def add_coords(coord, vect): | |
d_x, d_y = vect | |
x, y = coord | |
return x + d_x, y + d_y | |
class Tile: | |
def __init__(self, point=(0, 0)): | |
self.point = point | |
self.white = True | |
self.should_flip = False | |
def add(self, vect): | |
self.point = add_coords(vect, self.point) | |
def flip(self, force=False): | |
if self.should_flip or force: | |
self.white = not self.white | |
self.should_flip = False | |
def adj_black_count(self): | |
cnt = 0 | |
for direction in vector_map: | |
vect = vector_map[direction] | |
key = add_coords(self.point, vect) | |
if all_tiles.get(key) is None: | |
t = Tile(point=key) | |
all_tiles[key] = t | |
if not all_tiles[key].white: | |
cnt += 1 | |
return cnt | |
def decide(self): | |
if self.white and self.adj_black_count() == 2: | |
self.should_flip = True | |
elif not self.white and (self.adj_black_count() == 0 or self.adj_black_count() > 2): | |
self.should_flip = True | |
def __repr__(self): | |
return f'{hex(id(self))} white: {self.white} coord: {self.point}' | |
def parse_dir_tokens(line: str) -> List[str]: | |
tokens = [] | |
idx = 0 | |
while idx < len(line): | |
ch = line[idx] | |
if idx <= len(line) - 2: | |
ch2 = line[idx + 1] | |
if ch == 's': | |
if ch2 == 'w': | |
tokens.append('sw') | |
idx += 1 | |
elif ch2 == 'e': | |
tokens.append('se') | |
idx += 1 | |
elif ch == 'n': | |
if ch2 == 'w': | |
tokens.append('nw') | |
idx += 1 | |
elif ch2 == 'e': | |
tokens.append('ne') | |
idx += 1 | |
else: | |
tokens.append(ch) | |
else: | |
tokens.append(ch) | |
idx += 1 | |
return tokens | |
def flip_tile(instrs: List[str]): | |
tile = Tile() | |
for ist in instrs: | |
tile.add(vector_map[ist]) | |
if all_tiles.get(tile.point) is None: | |
all_tiles[tile.point] = tile | |
print(f'added {tile}') | |
else: | |
tile = all_tiles[tile.point] | |
print(f'reused {tile}') | |
tile.flip(True) | |
print(f'flipped {tile}') | |
def flip(coord): | |
if all_tiles.get(coord) is None: | |
all_tiles[coord] = Tile(point=coord) | |
all_tiles[coord].flip() | |
def day24(): | |
with open('day24input.txt', 'r') as f: | |
for line in f.readlines(): | |
tokens = parse_dir_tokens(line.strip('\n')) | |
print(tokens) | |
flip_tile(tokens) | |
print(sum([1 for key in all_tiles if not all_tiles[key].white])) | |
for i in range(1, 101): | |
for coord in [c for c in all_tiles]: | |
tile = all_tiles[coord] | |
tile.decide() | |
if not tile.white: | |
for direction in vector_map: | |
vect = vector_map[direction] | |
moved_coord = add_coords(coord, vect) | |
all_tiles[moved_coord].decide() | |
for coord in all_tiles: | |
tile = all_tiles[coord] | |
tile.flip() | |
print(f'day {i} black cnt: {sum([1 for key in all_tiles if not all_tiles[key].white])}') | |
if __name__ == '__main__': | |
day24() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment