aoc/2021/11/11.py
2021-12-18 10:40:06 -06:00

111 lines
2.1 KiB
Python

width = 10
height = 10
grid = {}
with open("input.txt") as f:
lines = f.read().split('\n')
for i in range(height):
for j in range(width):
grid[(i,j)] = int(lines[i][j])
def steps(grid, steps):
"""
Step through grid multiple times
and count the flashes.
"""
flashes = 0
for i in range(steps):
flashes += step(grid)
return flashes
def step(grid):
"""
Step through grid once
and count the flashes.
"""
increment(grid)
flashes = flash(grid)
return flashes
def increment(grid):
"""
Increment the entire grid.
"""
for i in range(height):
for j in range(width):
grid[(i,j)] += 1
def flash(grid):
"""
Calculate which octopi should flash.
Also count how many flashes.
"""
flashes = 0
flashed = set()
cascade = []
# find which octopi should flash and add them to queue
for i in range(height):
for j in range(width):
point = (i,j)
if grid[point] > 9 and point not in flashed:
flashed.add(point)
cascade += neighbors(point)
grid[point] = 0 # reset
flashes += 1
# process the queue of flashing octopi
while cascade:
point = cascade.pop()
# if it hasn't already flashed, increment its energy
if point not in flashed:
grid[point] = grid[point] + 1
# then figure out if it should flash
if grid[point] > 9 and point not in flashed:
flashed.add(point)
cascade += neighbors(point)
grid[point] = 0 # reset
flashes += 1
return flashes
def neighbors(point):
"""
Get a list of neighboring points,
diagonals included.
"""
i,j = point
n = [
(i-1,j-1),
(i-1,j),
(i-1,j+1),
(i,j-1),
#(i,j) is excluded
(i,j+1),
(i+1,j-1),
(i+1,j),
(i+1,j+1)
]
return [ (i,j) for (i,j) in n if (-1 < i < height) and (-1 < j < width) ]
def display(grid):
"""
Pretty print the grid.
"""
for i in range(height):
row = []
for j in range(width):
row.append(grid[(i,j)])
print(row)
grid1 = grid.copy()
part1 = steps(grid1,100)
#display(grid1)
print(part1)
grid2 = grid.copy()
from collections import Counter
i = 0
while True:
step(grid2)
i += 1
c = Counter(grid2.values())
if c[0] == width * height: # all are flashing at same time
break
print(i)