lines = open("inputs/day11.txt").readlines() def mkmat(lines): mat = [[0 if x == "." else 1 for x in line.strip("\n")] for line in lines] return mat def empty_spaces(mat): empty_lines = [] for idx, line in enumerate(mat): if sum(line) == 0: empty_lines.append(idx) empty_cols = [] for i in range(len(mat[0])): col = [x[i] for x in mat] if sum(col) == 0: empty_cols.append(i) return empty_lines, empty_cols def expand_mat(mat): empty_lines = [] for idx, line in enumerate(mat): if sum(line) == 0: empty_lines.append(idx) while empty_lines: idx = empty_lines.pop(0) mat.insert(idx, [0 for x in range(len(mat[0]))]) if empty_lines: empty_lines = [x+1 for x in empty_lines] empty_cols = [] for i in range(len(mat[0])): col = [x[i] for x in mat] if sum(col) == 0: empty_cols.append(i) while empty_cols: idx = empty_cols.pop(0) for line in mat: line.insert(idx, 0) if empty_cols: empty_cols = [x+1 for x in empty_cols] return mat def galaxies(mat): coords = [] for idx, line in enumerate(mat): for jdx, p in enumerate(line): if p == 1: coords.append((idx, jdx)) return coords def bfsdistances(coords, mat): dists = [[0 for x in range(len(coords))] for y in range(len(coords))] for idx, coord in enumerate(coords): paths = bfs(coord, mat) for jdx, path in enumerate(paths): dists[idx][jdx] = len(path) return dists def manhattendistances(coords, expansions, expansionrate=1000000-1): (rows, cols) = expansion dists = [[0 for x in range(len(coords))] for y in range(len(coords))] for i, coord1 in enumerate(coords): for j, coord2 in enumerate(coords): emptyrows = len([x for x in range(coord1[0], coord2[0]+1) if x in rows]) + len([x for x in range(coord1[0], coord2[0]+1)[::-1] if x in rows]) emptycols = len([x for x in range(coord1[1], coord2[1]+1) if x in cols]) + len([x for x in range(coord1[1], coord2[1]+1)[::-1] if x in cols]) d = manhatten(coord1, coord2) + ((emptyrows+emptycols) * expansionrate) dists[i][j] = d return dists def manhatten(x,d): (x,y) = x (dx, dy) = d return abs(x-dx) + abs(y-dy) def bfs(start, maze): paths = [] directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] stack = [(start, [])] visited = [[0 for x in range(len(mat[0]))] for y in range(len(mat))] visited[start[0]][start[1]] = 1 while stack: (x,y), path = stack.pop(0) for dx, dy in directions: newx, newy = x+dx, y+dy if 0 <= newx < len(mat) and 0 <= newy < len(mat[0]) and visited[newx][newy] == 0: new_path = path + [(newx, newy)] if mat[newx][newy] == 1: paths.append(new_path) else: stack.append(((newx, newy), new_path)) visited[newx][newy] = 1 return paths mat = mkmat(lines) expansion = empty_spaces(mat) #mat = expand_mat(mat) coords = galaxies(mat) dists = manhattendistances(coords, expansion) s = 0 for d in dists: # print(len(d)) s += sum(d) print(s//2)