from lib import get_data, Grid2D from copy import deepcopy def part_2(data, target=10): g = Grid2D(data) seen = {} i = 0 while i < target: ng = deepcopy(g) for r in range(g.n_rows): for c in range(g.n_cols): if g[(r, c)] == ".": tree_count = sum( [1 if g[nb] == "|" else 0 for nb in g.neighbors_adj((r, c))] ) if tree_count >= 3: ng[(r, c)] = "|" elif g[(r, c)] == "|": lumber_count = sum( [1 if g[nb] == "#" else 0 for nb in g.neighbors_adj((r, c))] ) if lumber_count >= 3: ng[(r, c)] = "#" elif g[(r, c)] == "#": tree_count = sum( [1 if g[nb] == "|" else 0 for nb in g.neighbors_adj((r, c))] ) lumber_count = sum( [1 if g[nb] == "#" else 0 for nb in g.neighbors_adj((r, c))] ) if tree_count > 0 and lumber_count > 0: pass else: ng[(r, c)] = "." else: assert False h = ng.hash() if h in seen: delta = i - seen[h] while (i + delta) < target: i += delta seen = {} else: seen[h] = i i += 1 g = ng w = 0 l = 0 for r in range(g.n_rows): for c in range(g.n_cols): if g[(r, c)] == "|": w += 1 elif g[(r, c)] == "#": l += 1 print(l * w) def main(): data = get_data(__file__) part_2(data, 10) part_2(data, 1000000000) if __name__ == "__main__": main()