advent-of-code/2021/python/day11.py

91 lines
2.3 KiB
Python

import matrix
import shared
import sys
import numpy as np
from scipy import ndimage
from pprint import pprint as pp
class Syntax:
def __init__(self, name):
mx = shared.load_file_int_matrix(name)
self.mx = np.array(mx)
self.flash_count = 0
self.step_count = 0
def check_syncronized(self):
cpy = np.copy(self.mx)
flat = np.ravel(cpy)
if np.all(flat == 10):
return True
def step(self):
self.step_count += 1
self.increment_all()
# Get a 2darray of bools of whether it's flashing
self.flashed = (self.mx > 9).astype(int)
flash_coords = np.argwhere(self.flashed == 1) # get a list of any flashed
if len(flash_coords) == 0:
return
self.flash_count += len(flash_coords)
if flash_coords.any():
for coord in flash_coords:
self.flash({"c": coord[1], "r": coord[0]})
if self.check_syncronized():
return True
self.reset_flashes()
#matrix.pmx(self.mx, self.flashed) # Print a pretty matrix
def flash(self, coord: dict) -> np.ndarray:
neighbor_coords = matrix.get_neighbor_coords(
self.mx, c=coord["c"], r=coord["r"]
)
for c, val in neighbor_coords:
self.add_clamp(**c)
if self.flashed[c["r"]][c["c"]]:
continue
if self.mx[c["r"]][c["c"]] > 9:
self.flash_count += 1
self.flashed[c["r"]][c["c"]] = 1
self.flash(c)
def reset_flashes(self):
for r, row in enumerate(self.mx):
for c, col in enumerate(row):
if self.mx[r][c] == 10:
self.mx[r][c] = 0
def add_clamp(self, c, r):
""" Clamp to 10, but add 1 """
if self.mx[r][c] < 10:
self.mx[r][c] += 1
def increment_all(self):
for r, row in enumerate(self.mx):
for c, _ in enumerate(row):
self.add_clamp(c, r)
def main():
s = Syntax(shared.get_fname(11))
print(f"before any steps")
matrix.pmx(s.mx)
print("----")
for x in range(9999):
if s.step():
print(x)
break
matrix.pmx(s.mx)
print(s.flash_count)
print(s.step_count)
if __name__ == "__main__":
main()