104
day11/day11.py
Executable file
104
day11/day11.py
Executable file
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
from typing import Sequence, Tuple, Set
|
||||
from copy import deepcopy
|
||||
|
||||
|
||||
Point = Tuple[int, int]
|
||||
|
||||
|
||||
class Grid:
|
||||
def __init__(self, grid: Sequence[Sequence[int]]):
|
||||
self.grid = grid
|
||||
self.rows = len(grid)
|
||||
self.cols = len(grid[0]) if self.rows else 0
|
||||
|
||||
def neighbors(self, point: Point) -> Set[Point]:
|
||||
i, j = point
|
||||
return {
|
||||
(r, c)
|
||||
for r, c in [
|
||||
(i - 1, j - 1),
|
||||
(i - 1, j + 1),
|
||||
(i + 1, j - 1),
|
||||
(i + 1, j + 1),
|
||||
(i, j - 1),
|
||||
(i, j + 1),
|
||||
(i - 1, j),
|
||||
(i + 1, j),
|
||||
]
|
||||
if 0 <= r < self.rows and 0 <= c < self.cols
|
||||
}
|
||||
|
||||
def step(self):
|
||||
# Add 1 to everything
|
||||
for i in range(self.rows):
|
||||
for j in range(self.cols):
|
||||
self.grid[i][j] += 1
|
||||
|
||||
# "Apply" grid - increments to add to each grid item
|
||||
apply = [[0 for _ in row] for row in self.grid]
|
||||
flashed = [[False for _ in row] for row in self.grid]
|
||||
|
||||
while True:
|
||||
changed = False
|
||||
|
||||
for i in range(self.rows):
|
||||
for j in range(self.cols):
|
||||
if self.grid[i][j] > 9 and not flashed[i][j]:
|
||||
flashed[i][j] = True
|
||||
changed = True
|
||||
for ni, nj in self.neighbors((i, j)):
|
||||
self.grid[ni][nj] += 1
|
||||
|
||||
if not changed:
|
||||
break
|
||||
# Now, reset anything greater than 9 to 0
|
||||
for i in range(self.rows):
|
||||
for j in range(self.cols):
|
||||
if self.grid[i][j] > 9:
|
||||
self.grid[i][j] = 0
|
||||
|
||||
def __getitem__(self, key: Point) -> int:
|
||||
r, c = key
|
||||
return self.grid[r][c]
|
||||
|
||||
def __str__(self) -> str:
|
||||
lines = []
|
||||
for row in self.grid:
|
||||
line = ""
|
||||
for col in row:
|
||||
if col == 0:
|
||||
line += "\u001b[34;1m0\u001b[0m"
|
||||
else:
|
||||
line += str(col)
|
||||
lines += [line]
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
grid = Grid([[int(c) for c in line.strip()] for line in sys.stdin])
|
||||
|
||||
|
||||
def part1(grid: Grid):
|
||||
flashes = 0
|
||||
for step in range(100):
|
||||
grid.step()
|
||||
for row in grid.grid:
|
||||
for col in row:
|
||||
if col == 0:
|
||||
flashes += 1
|
||||
print(flashes)
|
||||
|
||||
|
||||
def part2(grid: Grid):
|
||||
steps = 0
|
||||
while any(any(col != 0 for col in row) for row in grid.grid):
|
||||
grid.step()
|
||||
steps += 1
|
||||
print(steps)
|
||||
|
||||
|
||||
print("Part 1")
|
||||
part1(deepcopy(grid))
|
||||
print("Part 2")
|
||||
part2(grid)
|
||||
Reference in New Issue
Block a user