lines = [] with open("11.input") as f: for line in f.readlines(): lines.append(list(line.strip())) def pretty_print(map): print('=' * 20) for line in map: for c in line: print(c, end='') print("") def occupied_count(map, x_in, y_in, distance): dirs = [ (-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1), ] count = 0 for (y_dir, x_dir) in dirs: for i in range(1, distance + 1): y = y_in + y_dir * i x = x_in + x_dir * i if y < 0: break if x < 0: break if y > len(map) - 1: break if x > len(map[0]) - 1: break char = map[y][x] if char == '.': continue elif char == 'L': break elif char == '#': count += 1 break return count def transform(map, distance, tolerance): next = list(map) for (y, line) in enumerate(map): next[y] = list(line) for (x, char) in enumerate(line): if char == '.': continue elif char == 'L': if occupied_count(map, x, y, distance) == 0: next[y][x] = '#' elif char == '#': if occupied_count(map, x, y, distance) >= tolerance: next[y][x] = 'L' return next def iterate(map, distance, tolerance): current = map while True: next = transform(current, distance, tolerance) #pretty_print(next) if next == current: break current = next return current print(len([c for l in iterate(lines, 1, 4) for c in l if c == '#'])) print(len([c for l in iterate(lines, 1000, 5) for c in l if c == '#'])) current = lines