···11+import fileinput
22+from utils import new_table
33+44+55+def lit_pixels(grid):
66+ return sum(sum(c == '#' for c in row) for row in grid)
77+88+99+GRID = [
1010+ ['.', '#', '.'],
1111+ ['.', '.', '#'],
1212+ ['#', '#', '#'],
1313+]
1414+1515+RULES = {}
1616+1717+for line in fileinput.input():
1818+ rule_in, rule_out = line.split(' => ')
1919+2020+ # Build all rule rotations and reflections
2121+ grid = [list(x) for x in rule_in.split('/')]
2222+ n = 2 if rule_in.count('/') == 1 else 3
2323+2424+ for _ in range(4):
2525+ norm = ''.join(''.join(p) for p in grid)
2626+ refl = ''.join(''.join(p[::-1]) for p in grid)
2727+ RULES[norm] = RULES[refl] = rule_out.replace('/', '')
2828+2929+ rotated = new_table(None, width=n, height=n)
3030+3131+ for y in range(n):
3232+ for x in range(n):
3333+ rotated[y][x] = grid[n - x - 1][y]
3434+3535+ grid = rotated
3636+3737+for i in range(18):
3838+ size = len(GRID[0])
3939+ d = 2 if size % 2 == 0 else 3
4040+4141+ new_size = (size // d) * (d + 1)
4242+ new_grid = new_table(None, width=new_size, height=new_size)
4343+4444+ for y in range(size // d):
4545+ for x in range(size // d):
4646+ # Build the string representation of each 2x2 or 3x3 subgrid
4747+ subgrid = ''
4848+4949+ for k in range(d):
5050+ subgrid += ''.join(GRID[y*d + k][x*d:(x+1)*d])
5151+5252+ # Lookup the corresponding rule and populate the new grid
5353+ out = RULES[subgrid]
5454+ for ny in range(d+1):
5555+ for nx in range(d+1):
5656+ new_grid[y*(d+1) + ny][x*(d+1) + nx] = out[ny*(d+1) + nx]
5757+5858+ GRID = new_grid
5959+6060+ if i == 4:
6161+ print "Lit pixels after 5 iterations:", lit_pixels(GRID)
6262+6363+print "Lit pixels after 18 iterations:", lit_pixels(GRID)