from typing import Any, Iterator, Literal, cast import numpy as np import parse # type: ignore from ..base import BaseSolver class Solver(BaseSolver): def solve(self, input: str) -> Iterator[Any]: lights_1 = np.zeros((1000, 1000), dtype=bool) lights_2 = np.zeros((1000, 1000), dtype=int) for line in input.splitlines(): action, sx, sy, ex, ey = cast( tuple[Literal["turn on", "turn off", "toggle"], int, int, int, int], parse.parse("{} {:d},{:d} through {:d},{:d}", line), # type: ignore ) ex, ey = ex + 1, ey + 1 match action: case "turn on": lights_1[sx:ex, sy:ey] = True lights_2[sx:ex, sy:ey] += 1 case "turn off": lights_1[sx:ex, sy:ey] = False lights_2[sx:ex, sy:ey] = np.maximum(lights_2[sx:ex, sy:ey] - 1, 0) case "toggle": lights_1[sx:ex, sy:ey] = ~lights_1[sx:ex, sy:ey] lights_2[sx:ex, sy:ey] += 2 yield lights_1.sum() yield lights_2.sum()