Takodachi! Advent Of Code 2021, Day 11

Towards world domINAtion!

#!/usr/bin/env python3

import numpy as np
from functools import reduce

input = """1224346384
5621128587
6388426546
1556247756
1451811573
1832388122
2748545647
2582877432
3185643871
2224876627"""


def flash(iter, takodachi, count, all_flash, flash_threshold=10):
    takodachi += 1
    width, height = takodachi.shape
    old = set()
    while True:
        flash_mask = np.where(np.greater_equal(takodachi, flash_threshold))
        d = list(set([(flash_mask[0][i], flash_mask[1][i]) for i in range(len(flash_mask[0]))]).difference(old))
        if len(d) > 0:
            mask = (np.array([d[i][0] for i in range(len(d))]), np.array([d[i][1] for i in range(len(d))]))
            old = old.union(set([(mask[0][i], mask[1][i]) for i in range(len(mask[0]))]))
            adjacents = []
            for x in [-1, 0, 1]:
                for y in [-1, 0, 1]:
                    if x != 0 or y != 0:
                        mx = mask[0] + x
                        my = mask[1] + y
                        keep = np.where((mx >= 0) & (mx < width) & (my >= 0) & (my < width))[0]
                        adjacents.append((mx[keep], my[keep]))
            for adjacents_mask in adjacents:
                takodachi[adjacents_mask] += 1
        else:
            break

    d = list(old)
    flashes = len(d)
    mask = (np.array([d[i][0] for i in range(flashes)]), np.array([d[i][1] for i in range(flashes)]))
    if flashes > 0:
        takodachi[mask] = 0
        if flashes == width * height:
            all_flash.append(iter + 1)
    return takodachi, flashes + count, all_flash


if __name__ == '__main__':
    width = len(input.split("\n", 1)[0])
    n = np.array([c for c in input.replace('\n', '')], dtype=int)
    tako = n.reshape(width, -1)
    max_step = 500
    tako, flashes, all_flashes = reduce(lambda acc, iter: flash(iter, acc[0], acc[1], acc[2]), np.arange(max_step), (tako, 0, []))
    print(tako, flashes, all_flashes[0])

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.