/ Python / 2018 / 18.py
18.py
 1  from lib import *
 2  
 3  input = read_input(2018, 18)
 4  
 5  
 6  def cntAdj(grid, y, x, t):
 7      return sum(
 8          grid[i][j] == t
 9          for i in range(y - 1, y + 2)
10          for j in range(x - 1, x + 2)
11          if (i, j) != (y, x) and i in range(len(grid)) and j in range(len(grid[i]))
12      )
13  
14  
15  grid = input.splitlines()
16  for _ in range(10):
17      new_grid = []
18      for i, line in enumerate(grid):
19          new_line = ""
20          for j, c in enumerate(line):
21              if c == "." and cntAdj(grid, i, j, "|") >= 3:
22                  new_line += "|"
23              elif c == "|" and cntAdj(grid, i, j, "#") >= 3:
24                  new_line += "#"
25              elif c == "#" and not (cntAdj(grid, i, j, "#") >= 1 and cntAdj(grid, i, j, "|") >= 1):
26                  new_line += "."
27              else:
28                  new_line += c
29          new_grid.append(new_line)
30      grid = new_grid
31  
32  a = sum(line.count("|") for line in grid)
33  b = sum(line.count("#") for line in grid)
34  print(a * b)
35  
36  
37  def next_iteration(grid):
38      new_grid = []
39      for i, line in enumerate(grid):
40          new_line = ""
41          for j, c in enumerate(line):
42              if c == "." and cntAdj(grid, i, j, "|") >= 3:
43                  new_line += "|"
44              elif c == "|" and cntAdj(grid, i, j, "#") >= 3:
45                  new_line += "#"
46              elif c == "#" and not (cntAdj(grid, i, j, "#") >= 1 and cntAdj(grid, i, j, "|") >= 1):
47                  new_line += "."
48              else:
49                  new_line += c
50          new_grid.append(new_line)
51      return new_grid
52  
53  
54  grid = input.splitlines()
55  seen = {}
56  i = 0
57  while tuple(grid) not in seen:
58      seen[tuple(grid)] = i
59      grid = next_iteration(grid)
60      i += 1
61  
62  cycle = i - seen[tuple(grid)]
63  for _ in range((1000000000 - i) % cycle):
64      grid = next_iteration(grid)
65  
66  a = sum(line.count("|") for line in grid)
67  b = sum(line.count("#") for line in grid)
68  print(a * b)