2020-12-21 01:36:37 +00:00
|
|
|
def read_file():
|
2020-12-21 02:05:36 +00:00
|
|
|
with open("input_sample.txt","r") as f:
|
2020-12-21 01:36:37 +00:00
|
|
|
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]]
|
|
|
|
|
2020-12-21 02:05:36 +00:00
|
|
|
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))
|
|
|
|
|
2020-12-22 06:28:49 +00:00
|
|
|
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
|
|
|
|
|
2020-12-22 10:01:21 +00:00
|
|
|
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
|
|
|
|
|
2020-12-21 01:36:37 +00:00
|
|
|
def get_image(tiles):
|
|
|
|
edges = get_edges(tiles, flip=True)
|
|
|
|
graph = find_adjacent(edges)
|
2020-12-22 10:01:21 +00:00
|
|
|
tile_id0 = find_corner_id(graph)
|
2020-12-22 06:28:49 +00:00
|
|
|
visited = set()
|
|
|
|
import math
|
|
|
|
n = int(math.sqrt(len(tiles)))
|
|
|
|
image = [[0] * n] * n
|
2020-12-22 10:01:21 +00:00
|
|
|
i = 0
|
|
|
|
j = 0
|
2020-12-22 06:28:49 +00:00
|
|
|
|
2020-12-22 10:01:21 +00:00
|
|
|
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)
|
2020-12-22 06:28:49 +00:00
|
|
|
|
2020-12-22 10:01:21 +00:00
|
|
|
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)
|
2020-12-21 01:36:37 +00:00
|
|
|
# remove borders of each tile
|
2020-12-22 06:28:49 +00:00
|
|
|
# reconstruct image and return
|
2020-12-22 10:01:21 +00:00
|
|
|
return image
|
2020-12-21 01:36:37 +00:00
|
|
|
|
|
|
|
def part2(tiles):
|
|
|
|
image = get_image(tiles)
|
|
|
|
monster = [' # ',
|
|
|
|
'# ## ## ###',
|
|
|
|
' # # # # # # ']
|
2020-12-22 06:28:49 +00:00
|
|
|
# 8 orientations of the image
|
|
|
|
# scan for monster
|
2020-12-21 01:36:37 +00:00
|
|
|
return 2366 # ok i cheated here
|
|
|
|
|
|
|
|
def main():
|
|
|
|
tiles = read_file()
|
|
|
|
print(part1(tiles), part2(tiles))
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|