def main(d): # create a set of tuples seed = open('input.txt').read().split('\n') active = set( (d - 2) * (0,) + (i, j) # zero-pad coords for i, row in enumerate(seed) for j, cell in enumerate(row) if cell == '#' ) # generate all tuples -1..1 in all dimensions neighboring = [()] # list contains empty tuple which will be iterated over for _ in range(d): neighboring = [ t + (x,) for x in [-1, 0, 1] for t in neighboring ] neighboring.remove(d * (0,)) # this is the center cell # do 6 iterations according to rules from collections import Counter for _ in range(6): active = set( t for t, count in Counter( # unpack the tuple and its count of neighboring active cells tuple(map(sum, zip(t, n))) # add neighbors kernel to each active cell for t in active for n in neighboring ).items() if count == 3 or t in active and count == 2 ) return len(active) print(main(3), main(4))