Advent of Code Day 24

In [2]:
def readfile(input_name):
    with open(input_name) as input_file:
        return input_file.read().rstrip('\n')
In [4]:
input24 = readfile("AoC/input24.txt")
In [40]:
def n(grid):
    return "".join(["".join(x) for x in grid])

def life(input24):
    grid = [[x for x in line] for line in input24.split("\n")]

    seen_grids = set()
    seen_grids.add(n(grid))


    while True:
        next_grid = []
        for i in range(5):
            next_grid.append(['.'] * 5)

        for y in range(5):
            for x in range(5):
                neighbours = 0
                for yy, xx in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
                    bug = False
                    if y + yy >= 0 and y + yy <= 4 and x + xx >= 0 and x + xx <= 4:
                        bug = grid[y + yy][x + xx] == '#' 

                    if bug:
                        neighbours += 1 

                if grid[y][x] == '#' and neighbours == 1:
                    next_grid[y][x] = '#'
                elif grid[y][x] == '.' and (neighbours == 1 or neighbours == 2):
                    next_grid[y][x] = '#'

        nng = n(next_grid)
        for y in next_grid:
            for x in y:
                print(x, end="")
            print()
        print()
        
        
        if nng in seen_grids:
            return nng

        seen_grids.add(nng)
        grid = next_grid

def cost(s):
    total = 0
    for i, x in enumerate(s):
        if x == '#':
            total += pow(2, i)
    return total
        
    
cost(life(input24))
# cost(life("""....#
# #..#.
# #..##
# ..#..
# #...."""))
.##.#
##.##
#.##.
###.#
.#.#.

#.#.#
.....
.....
.....
##..#

.#.#.
#.#.#
.....
##..#
####.

#...#
.....
###.#
..##.
...##

.#.#.
###.#
#....
##...
..#.#

##..#
..#..
..#.#
.##.#
##.#.

####.
#####
.#.##
#...#
#...#

....#
.....
.#...
##.#.
##.##

...#.
.#..#
####.
..###
..#.#

.##.#
###..
#....
##...
.##.#

#..#.
...##
..#..
..#.#
#.##.

.####
#.#.#
.####
##...
.#.##

##...
.....
.....
#.###
#####

###..
##...
#.###
#....
.....

..##.
...##
..#.#
#####
#....

.##.#
.....
###..
.....
#####

####.
###.#
#.##.
#####
#...#

...##
.....
.....
.....
#####

..###
...##
.....
#####
#...#

.##..
..#..
#####
.....
#####

##.#.
#..##
#...#
#####
#...#

.####
.##..
.##..
.....
#####

#...#
#..##
#..#.
#####
#...#

##.##
.##..
.##..
.....
#####

#..##
#..##
#..#.
#####
#...#

###..
.##..
.##..
.....
#####

#..#.
#..#.
#..#.
#####
#...#

#####
.##.#
.##.#
.....
#####

#....
#....
#..##
#####
#...#

##...
.#.##
.##..
.....
#####

#.###
#..##
#.###
#####
#...#

###..
.#...
.....
.....
#####

#.##.
###..
.#...
#####
#...#

#..##
...#.
...##
.....
#####

.##.#
#.#..
..#.#
#####
#...#

##.#.
...##
##..#
.....
#####

#####
###..
#####
#####
#...#

....#
....#
.....
.....
#####

...##
...##
....#
#####
#...#

..#..
..#..
###..
.....
#####

.###.
##.#.
#..#.
#####
#...#

#...#
....#
..#.#
.....
#####

.#.##
#.##.
.#.##
#####
#...#

#...#
..#..
.#...
.....
#####

.###.
##.##
#.#..
#####
#...#

#...#
....#
..#.#
.....
#####

Out[40]:
32526865
In [64]:
def list_neighbours(x, y, z):
    ns = []
    for xx, yy in [(-1, 0), (0, 1), (1, 0), (0, -1)]:
        xxx = xx + x
        yyy = yy + y

        handled = False
        if xxx < 0 or xxx > 4:
            ns.append((2 + xx, 2, z + 1))
            handled = True

        if yyy < 0 or yyy > 4:
            ns.append((2, 2 + yy, z + 1))
            handled = True

        if xxx == 2 and yyy == 2:
            ns.extend((k if xx == 0 else (0 if xx == 1 else 4), k if yy == 0 else (0 if yy == 1 else 4),  z - 1) for k in range(5))
            handled = True

        if not handled:
            ns.append((xxx, yyy, z))
    return ns

def life2(input24):
    start_grid = [[x for x in line] for line in input24.split("\n")]
    grid = {}
    for j, y in enumerate(start_grid):
        for i, x in enumerate(y):
            if i == 2 and j == 2:
                continue

            grid[(i, j, 0)] = x

    start_level = -1
    end_level = 1

    minutes = 0
    while minutes < 200:
        print(".", end="")
        minutes += 1

        next_grid = {}
        for z in range(start_level, end_level + 1):
            for y in range(5):
                for x in range(5):
                    if x == 2 and y == 2:
                        continue

                    neighbours = 0

                    for n in list_neighbours(x, y, z):
                        if grid.get(n, '.') == '#':
                            neighbours += 1

                    condition = grid.get((x, y, z), '.') == '#' and neighbours == 1
                    condition = condition or grid.get((x, y, z), '.') == '.' and (neighbours == 1 or neighbours == 2)
                    if condition:
                        next_grid[(x, y, z)] = '#'
                        if z - 1 < start_level:
                            start_level = z - 1
                        if z + 1 > end_level:
                            end_level = z + 1
                    else:
                        next_grid[(x, y, z)] = '.'
        grid = next_grid

    return sum(1 for v in grid.values() if v == '#')

life2(input24)
........................................................................................................................................................................................................
Out[64]:
2009