From 68d99c78904c8bf111f219f1444ce96c56ff5226 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Wed, 21 May 2025 23:06:42 +0100 Subject: [PATCH] 2015: d18: ex2: add solution --- 2015/d18/ex2/ex2.py | 70 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100755 2015/d18/ex2/ex2.py diff --git a/2015/d18/ex2/ex2.py b/2015/d18/ex2/ex2.py new file mode 100755 index 0000000..f39b6da --- /dev/null +++ b/2015/d18/ex2/ex2.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python + +import itertools +import sys +from collections.abc import Iterator +from typing import NamedTuple + + +class Point(NamedTuple): + x: int + y: int + + +def solve(input: str) -> int: + def parse(input: str) -> set[Point]: + return { + Point(x, y) + for x, line in enumerate(input.splitlines()) + for y, c in enumerate(line) + if c == "#" + } + + def neighbours(p: Point) -> Iterator[Point]: + for dx, dy in itertools.product((-1, 0, 1), repeat=2): + if dx == 0 and dy == 0: + continue + yield Point(p.x + dx, p.y + dy) + + def step(lights: set[Point], dimensions: Point) -> set[Point]: + res = { + # Four corners are stuck on + Point(0, 0), + Point(0, dimensions.y - 1), + Point(dimensions.x - 1, 0), + Point(dimensions.x - 1, dimensions.y - 1), + } + for p in map( + Point._make, + itertools.product(range(dimensions.x), range(dimensions.y)), + ): + num_alive = sum(n in lights for n in neighbours(p)) + if p in lights and num_alive not in (2, 3): + continue + if p not in lights and num_alive != 3: + continue + res.add(p) + + return res + + lights = parse(input) + dimensions = Point(100, 100) + lights |= { + # Four corners are stuck on + Point(0, 0), + Point(0, dimensions.y - 1), + Point(dimensions.x - 1, 0), + Point(dimensions.x - 1, dimensions.y - 1), + } + for _ in range(100): + lights = step(lights, dimensions) + return len(lights) + + +def main() -> None: + input = sys.stdin.read() + print(solve(input)) + + +if __name__ == "__main__": + main()