def readfile(input_name):
with open(input_name) as input_file:
return input_file.read().rstrip('\n')
input24 = readfile("AoC/input24.txt")
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("""....#
# #..#.
# #..##
# ..#..
# #...."""))
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)