Day 18 - Advent of Code 2015

Working solutions for the day 18 puzzles.

Part One

""" day_18_01.py """

# usage: python3 day_18_01.py < input

import itertools
import sys


deltas = list(itertools.product([-1, 0, 1], [-1, 0, 1]))
deltas.remove((0, 0))


def advance(grid, colrow):
    """ calculate next state using puzzle rules """
    def neighbours():
        """ calculate number of lit neighbours """
        count = 0
        for dx, dy in deltas:
            if (x + dx, y + dy) in grid:
                count += 1
        return count

    future = set()
    cols, rows = colrow
    for y in range(rows):
        for x in range(cols):
            if (x, y) in grid:
                if neighbours() in [2, 3]:
                    future.add((x, y))
            else:
                if neighbours() == 3:
                    future.add((x, y))
    return future


current = set()
for row, line in enumerate(sys.stdin.read().splitlines()):
    for col, state in enumerate(list(line)):
        if state == '#':
            current.add((col, row))
        size = (col + 1, row + 1)

for step in range(100):
    current = advance(current, size)
print(len(current))

Part Two

""" day_18_02.py """

# usage: python3 day_18_02.py < input

import itertools
import sys


deltas = list(itertools.product([-1, 0, 1], [-1, 0, 1]))
deltas.remove((0, 0))


def advance(grid, colrow):
    """ calculate next state using puzzle rules """
    def neighbours():
        """ calculate number of lit neighbours """
        count = 0
        for dx, dy in deltas:
            if (x + dx, y + dy) in grid:
                count += 1
        return count

    future = set()
    cols, rows = colrow
    for y in range(rows):
        for x in range(cols):
            if (x, y) in grid:
                if neighbours() in [2, 3]:
                    future.add((x, y))
            else:
                if neighbours() == 3:
                    future.add((x, y))
    return future


current = set()
for row, line in enumerate(sys.stdin.read().splitlines()):
    for col, state in enumerate(list(line)):
        if state == '#':
            current.add((col, row))
        size = (col + 1, row + 1)

width, height = size
corners = set(itertools.product([0, width - 1], [0, height - 1]))

current |= corners
for step in range(100):
    current = advance(current, size)
    current |= corners
print(len(current))