from time import sleep m = [] old_m = dict() with open('input.txt', 'r') as f: for line in f.readlines(): row = [] for sym in line.strip(): row.append(sym) m.append(row) def print_map(m): for row in m: print(''.join(row)) def get_adjacent(x, y): adj = [] for i in [-1, 0, 1]: for j in [-1, 0, 1]: if not (i == 0 and j == 0): if x + i < 0 or y + j < 0: continue try: adj.append(m[x + i][y + j]) except: pass return adj def get_res_val(m): num_trees = sum([row.count('|') for row in m]) num_lumb = sum([row.count('#') for row in m]) return num_lumb * num_trees for i in range(1000000000): i = i + 1 new_m = [] for x, row in enumerate(m): new_row = [] for y, sym in enumerate(row): adj = get_adjacent(x, y) num_trees = adj.count('|') num_lumb = adj.count('#') if sym == '.': res = '|' if num_trees >= 3 else sym elif sym == '|': res = '#' if num_lumb >= 3 else sym elif sym == '#': res = sym if num_lumb >= 1 and num_trees >= 1 else '.' new_row.append(res) new_m.append(new_row) m = new_m if m in old_m.values(): for j, tmp in old_m.items(): if tmp == m: break print(f'Loop detected: {j} and {i} are the same') break old_m[i] = m if i % 100 == 0: print(i, get_res_val(m)) loop_start = j first_iteration = i gap = first_iteration - loop_start tmp = (1000000000 - loop_start) % gap print('gap', gap) print('tmp', tmp) print(get_res_val(old_m[loop_start + tmp])) print(get_res_val(old_m[440])) # print_map(m) # print() # print_map(old_m[j])