69 lines
1.6 KiB
Python
69 lines
1.6 KiB
Python
#!/usr/bin/env python3
|
|
import fileinput
|
|
from pprint import pprint
|
|
from typing import List, Tuple, Any, Set, Generator
|
|
from timeit import timeit
|
|
|
|
|
|
lines = list(fileinput.input())
|
|
|
|
|
|
def neighborhood(
|
|
m: List[List[int]], x: int, y: int
|
|
) -> Generator[Tuple[int, int], None, None]:
|
|
h = ((-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1))
|
|
yield from (
|
|
(x_ + x, y_ + y)
|
|
for x_, y_ in h
|
|
if 0 <= x_ + x < len(m[0]) and 0 <= y_ + y < len(m)
|
|
)
|
|
|
|
|
|
def step(field):
|
|
for y in range(len(field)):
|
|
for x in range(len(field[y])):
|
|
field[y][x] += 1
|
|
|
|
flash_queue = [
|
|
(x, y)
|
|
for y in range(len(field))
|
|
for x in range(len(field[y]))
|
|
if field[y][x] > 9
|
|
]
|
|
|
|
flashed = set()
|
|
while flash_queue:
|
|
x, y = flash_queue.pop()
|
|
if (x, y) in flashed:
|
|
continue
|
|
flashed.add((x, y))
|
|
|
|
for x_, y_ in neighborhood(field, x, y):
|
|
field[y_][x_] += 1
|
|
if field[y_][x_] > 9 and (x_, y_) not in flashed:
|
|
flash_queue.append((x_, y_))
|
|
|
|
for x, y in flashed:
|
|
field[y][x] = 0
|
|
|
|
return len(flashed)
|
|
|
|
|
|
def main() -> Tuple[int, int]:
|
|
field = [[int(c) for c in line.strip()] for line in lines]
|
|
len_ = len(field) * len(field[0])
|
|
|
|
part1 = 0
|
|
part2 = 0
|
|
for part2 in range(100):
|
|
part1 += step(field)
|
|
|
|
while step(field) != len_ and sum(sum(row) for row in field) != 0:
|
|
part2 += 1
|
|
|
|
return part1, part2 + 2
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print(main())
|
|
print(f"{timeit(main, number=100) * 10:.3f} ms")
|