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()