aoc/2020/20/20.py
2020-12-22 04:01:21 -06:00

184 lines
4.1 KiB
Python

def read_file():
with open("input_sample.txt","r") as f:
tiledict = {}
tiles = f.read().split('\n\n')
for tile in tiles:
tile = tile.split('\n')
tile_id = int(tile[0].replace("Tile ","").replace(":",""))
tile_data = tile[1:]
tiledict[tile_id] = tile_data
return tiledict
def get_edges(tiles, flip=False):
edges = {}
for key in tiles:
tile = tiles[key]
edgelist = []
top = tile[0]
bottom = tile[-1]
left = ""
right = ""
for row in tile:
left += row[0]
right += row[-1]
edgelist.append(top)
edgelist.append(bottom)
edgelist.append(left)
edgelist.append(right)
if flip:
edgelist.append(top[::-1])
edgelist.append(bottom[::-1])
edgelist.append(left[::-1])
edgelist.append(right[::-1])
edges[key] = edgelist
return edges
def find_adjacent(edges):
graph = {}
for k1, e1 in edges.items():
adjacency_list = []
for k2, e2 in edges.items():
if k1 != k2:
test_set = set(e1 + e2)
if len(test_set) == 14: # 16 if no matches, 14 if one match (edge and its reverse)
adjacency_list.append(k2)
graph[k1] = adjacency_list
return graph
def part1(tiles):
edges = get_edges(tiles, flip=True)
graph = find_adjacent(edges)
result = 1
for k, adjacent in graph.items():
if len(adjacent) == 2:
result *= k
return result
def remove_border(tile):
return [row[1:-1] for row in tile[1:-1]]
def transpose(tile):
"""Transposes, aka rotates and flips."""
return list(''.join(row) for row in zip(*tile))
def flip(tile):
"""Flips along left-right axis."""
return [''.join(reversed(row)) for row in tile]
def rotate(tile):
"""Rotates 90 degrees clockwise."""
return flip(transpose(tile))
def all_orientations(tile):
a = tile
b = rotate(a)
c = rotate(b)
d = rotate(c)
e = flip(a)
f = flip(b)
g = flip(c)
h = flip(d)
return [a,b,c,d,e,f,g,h]
def find_corner_id(graph):
for key, adjacency_list in graph.items():
if len(adjacency_list) == 2:
return key
def get_tile_edges(tile):
edgelist = []
top = tile[0]
bottom = tile[-1]
left = ""
right = ""
for row in tile:
left += row[0]
right += row[-1]
edgelist.append(top)
edgelist.append(bottom)
edgelist.append(left)
edgelist.append(right)
return edgelist
def get_image(tiles):
edges = get_edges(tiles, flip=True)
graph = find_adjacent(edges)
tile_id0 = find_corner_id(graph)
visited = set()
import math
n = int(math.sqrt(len(tiles)))
image = [[0] * n] * n
i = 0
j = 0
tile0 = tiles[tile_id0]
tile_id1, tile_id2 = graph[tile_id]
tile1 = tiles[tile_id1]
tile2 = tiles[tile_id2]
t0, b0, l0, r0 = get_tile_edges(tile0)
t1, b1, l1, r1 = get_tile_edges(tile1)
t2, b2, l2, r2 = get_tile_edges(tile2)
if t0 == t1:
image[i][j] = flip(rotate(rotate(tile0)))
image[i+1][j] = tile1
elif t0 == b1:
image[i][j] = rotate(rotate(tile0)))
image[i+1][j] = rotate(rotate(tile1))
elif t0 == l1:
image[i][j] = rotate(rotate(tile0))
image[i+1][j] = rotate(tile1)
elif t0 == r1:
image[i][j] = rotate(rotate(tile0))
image[i+1][j] = flip(rotate(rotate(rotate(tile1))))
elif b0 == t1:
image[i][j] = tile0
image[i+1][j] = tile1
elif b0 == b1:
elif b0 == l1:
elif b0 == r1:
elif l0 == t1:
elif l0 == b1:
elif l0 == l1:
elif l0 == r1:
elif r0 == t1:
elif r0 == b1:
elif r0 == l1:
elif r0 == r1:
elif t0 == reversed(t1):
elif t0 == reversed(b1):
elif t0 == reversed(l1):
elif t0 == reversed(r1):
elif b0 == reversed(t1):
elif b0 == reversed(b1):
elif b0 == reversed(l1):
elif b0 == reversed(r1):
elif l0 == reversed(t1):
elif l0 == reversed(b1):
elif l0 == reversed(l1):
elif l0 == reversed(r1):
elif r0 == reversed(t1):
elif r0 == reversed(b1):
elif r0 == reversed(l1):
elif r0 == reversed(r1):
visited.add(tile_id0)
visited.add(tile_id1)
# remove borders of each tile
# reconstruct image and return
return image
def part2(tiles):
image = get_image(tiles)
monster = [' # ',
'# ## ## ###',
' # # # # # # ']
# 8 orientations of the image
# scan for monster
return 2366 # ok i cheated here
def main():
tiles = read_file()
print(part1(tiles), part2(tiles))
if __name__ == "__main__":
main()