import copy from pprint import pprint class PuzzleSolver: def __init__(self, filename): self.load(filename) def load(self, filename): with open(filename, "r", encoding="utf-8") as f: self.data = [list(x.rstrip()) for x in f.readlines()] self.width = len(self.data[0]) self.height = len(self.data) def occupied_adjacent(self, x, y): n = 0 for j in range(y-1, y+2): for i in range(x-1, x+2): if (i, j) == (x, y): continue if not (0 <= i < self.width): continue if not (0 <= j < self.height): continue s = self.get(i, j) if s == "#": n += 1 return n def get(self, x, y): return self.data[y][x] def mutate(self): ret = copy.deepcopy(self.data) for y in range(self.height): for x in range(self.width): s = self.get(x, y) if s == ".": continue n = self.occupied_adjacent(x, y) if s == "L": if n == 0: ret[y][x] = "#" elif s == "#": if n >= 4: ret[y][x] = "L" return ret def print(self): for y in range(self.height): print("".join(self.data[y])) print() def solve(self): stable = False rounds = 0 self.print() while not stable: x = self.mutate() stable = x == self.data self.data = x rounds += 1 self.print() return rounds def count_occupied(self): return sum([x.count("#") for x in self.data]) ps = PuzzleSolver("test.txt") rounds = ps.solve() cs = PuzzleSolver("test-1.txt") assert ps.data == cs.data ps = PuzzleSolver("data.txt") rounds = ps.solve() n = ps.count_occupied() print(f"There are {n} occupied seats.")