parent
236500a1ee
commit
94e6df7479
@ -0,0 +1,255 @@ |
|||||||
|
#!/usr/bin/env python |
||||||
|
|
||||||
|
from aoc import get_input # AoC |
||||||
|
import re # regex |
||||||
|
import numpy as np |
||||||
|
from copy import deepcopy as copy |
||||||
|
|
||||||
|
config = get_input(17).strip().split("\n") |
||||||
|
|
||||||
|
for i in range(len(config)): |
||||||
|
newlst = [] |
||||||
|
newlst[:0] = config[i] |
||||||
|
config[i] = newlst |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# network is a simple 3D cube |
||||||
|
|
||||||
|
# x * x * x |
||||||
|
|
||||||
|
initlen = len(config[0]) |
||||||
|
|
||||||
|
print(np.asarray(config)) |
||||||
|
print(f"{initlen=}") |
||||||
|
|
||||||
|
cube = np.asarray([ np.zeros((initlen,initlen), int) for z in range(initlen) ]) |
||||||
|
|
||||||
|
cube4 = np.asarray([[ np.zeros((initlen,initlen), int) for z in range(initlen) ] for w in range(initlen) ]) |
||||||
|
|
||||||
|
#apply config to network |
||||||
|
|
||||||
|
cubelen = initlen |
||||||
|
cubelen4 = initlen |
||||||
|
|
||||||
|
configZ = 1 |
||||||
|
#cube[configZ] = config |
||||||
|
|
||||||
|
for iy in range(len(config)): |
||||||
|
for ix in range(len(config)): |
||||||
|
if(config[iy][ix] == "."): |
||||||
|
cube[configZ][iy][ix] = 0 |
||||||
|
else: |
||||||
|
cube[configZ][iy][ix] = 1 |
||||||
|
|
||||||
|
for iy, row in enumerate(config): |
||||||
|
for ix, node in enumerate(row): |
||||||
|
val = 0 |
||||||
|
if( node == "#" ): |
||||||
|
val = 1 |
||||||
|
|
||||||
|
cube4[1][1][iy][ix] = val |
||||||
|
|
||||||
|
print(cube4, cube4.shape) |
||||||
|
|
||||||
|
|
||||||
|
def getpos(x, y, z, net=cube): |
||||||
|
netlen = net.shape[0] |
||||||
|
if(x in range(netlen) and y in range(netlen) and z in range(netlen)): |
||||||
|
return net[z][y][x] |
||||||
|
else: |
||||||
|
return None |
||||||
|
|
||||||
|
def setpos(x, y, z, val, net=cube): |
||||||
|
netlen = net.shape[0] |
||||||
|
if( x in range(netlen) and y in range(netlen) and z in range(netlen) ): |
||||||
|
net[z][y][x] = val |
||||||
|
else: |
||||||
|
return None |
||||||
|
|
||||||
|
def countaround(x, y, z, net=cube): |
||||||
|
px = [-1, 0, 1] |
||||||
|
py = [-1, 0, 1] |
||||||
|
pz = [-1, 0, 1] |
||||||
|
|
||||||
|
around = dict() |
||||||
|
count = 0 |
||||||
|
checkcount = 0 |
||||||
|
|
||||||
|
for iz in pz: |
||||||
|
for iy in py: |
||||||
|
for ix in px: |
||||||
|
pos = (x+ix, y+iy, z+iz) |
||||||
|
|
||||||
|
if( pos != (x, y, z) ): |
||||||
|
checkcount += 1 |
||||||
|
|
||||||
|
val = getpos(pos[0], pos[1], pos[2], net) |
||||||
|
around[pos] = val |
||||||
|
|
||||||
|
if( val ): |
||||||
|
count += val |
||||||
|
|
||||||
|
return count, checkcount |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
offset4 = set() |
||||||
|
for x in range(-1, 2): |
||||||
|
for y in range(-1, 2): |
||||||
|
for z in range(-1, 2): |
||||||
|
for w in range(-1, 2): |
||||||
|
if( (x, y, z, w) != (0, 0, 0, 0) ): |
||||||
|
offset4.add( (x, y, z, w) ) |
||||||
|
|
||||||
|
def getpos4(x, y, z, w, net=cube4): |
||||||
|
netlen = net.shape[0] |
||||||
|
if(x in range(netlen) and y in range(netlen) and z in range(netlen) and w in range(netlen)): |
||||||
|
return net[w][z][y][x] |
||||||
|
else: |
||||||
|
return None |
||||||
|
|
||||||
|
def setpos4(x, y, z, w, val, net=cube4): |
||||||
|
netlen = net.shape[0] |
||||||
|
if(x in range(netlen) and y in range(netlen) and z in range(netlen) and w in range(netlen)): |
||||||
|
net[w][z][y][x] = val |
||||||
|
|
||||||
|
def countaround4D(x, y, z, w, net=cube4): |
||||||
|
count = 0 |
||||||
|
checkcount = 0 |
||||||
|
for diff in offset4: |
||||||
|
val = getpos4(x+diff[0], y+diff[1], z+diff[2], w+diff[3], net) |
||||||
|
checkcount += 1 |
||||||
|
if( val == 1 ): |
||||||
|
count += 1 |
||||||
|
return count, checkcount |
||||||
|
|
||||||
|
|
||||||
|
def printLayer(z, net=cube): |
||||||
|
print("Layer ", z) |
||||||
|
for l in net[z]: |
||||||
|
for char in l: |
||||||
|
#print(f"{char} ", end="") |
||||||
|
if(char): |
||||||
|
print("# ", end="") |
||||||
|
else: |
||||||
|
print(". ", end="") |
||||||
|
print("") |
||||||
|
print("----") |
||||||
|
|
||||||
|
|
||||||
|
def expandCube(net=cube, expand=1): |
||||||
|
net = np.pad(net, pad_width=expand, mode='constant', constant_values=0) |
||||||
|
cubelen = net.shape[0] |
||||||
|
return net, cubelen |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#expandCube(cube, cycles) |
||||||
|
cycles = 6 |
||||||
|
def runCycle(net, c=0, maxc=cycles, expand=False, ignoreCfgLayer=False): |
||||||
|
if( not c < maxc ): |
||||||
|
print("Done") |
||||||
|
return net |
||||||
|
|
||||||
|
if(expand): |
||||||
|
net, cubelen = expandCube(net, 1) |
||||||
|
newcube = net.copy() |
||||||
|
cubelen = net.shape[0] |
||||||
|
|
||||||
|
for z in range(cubelen): |
||||||
|
printLayer(z, net) |
||||||
|
|
||||||
|
|
||||||
|
for iz in range(cubelen): |
||||||
|
if(iz == 1 and ignoreCfgLayer): |
||||||
|
continue |
||||||
|
|
||||||
|
for iy in range(cubelen): |
||||||
|
for ix in range(cubelen): |
||||||
|
|
||||||
|
node = getpos(ix, iy, iz, net) |
||||||
|
activeCount, checkdCount = countaround(ix, iy, iz, net) |
||||||
|
newnode = node |
||||||
|
|
||||||
|
if( node == 1 and not activeCount in [2, 3] ): |
||||||
|
newnode = 0 |
||||||
|
if( node == 0 and activeCount == 3 ): |
||||||
|
newnode = 1 |
||||||
|
|
||||||
|
setpos(ix, iy, iz, newnode, newcube) |
||||||
|
|
||||||
|
print(f"{c=} : {ix=} {iy=} {iz=} / {cubelen=} : {checkdCount=} : {activeCount=} {node=} {newnode=} : {activeCount in [2,3]=}") |
||||||
|
print("") |
||||||
|
|
||||||
|
|
||||||
|
# Print the new layers |
||||||
|
print("orig", end=" ") |
||||||
|
printLayer(iz, net) |
||||||
|
print("new", end=" ") |
||||||
|
printLayer(iz, newcube) |
||||||
|
#print(newcube) |
||||||
|
|
||||||
|
print("New cycle\n") |
||||||
|
net = newcube |
||||||
|
|
||||||
|
return runCycle(net, c+1, expand=True, ignoreCfgLayer=ignoreCfgLayer) |
||||||
|
|
||||||
|
# print("###################################") |
||||||
|
# cube, cubelen = expandCube(cube, 10) |
||||||
|
# endcube = runCycle(cube) |
||||||
|
# print(endcube) |
||||||
|
# print( np.sum(endcube) ) |
||||||
|
|
||||||
|
cycles = 6 |
||||||
|
def runCycle4(net, c=0, maxc=cycles, expand=False): |
||||||
|
if( not c < maxc ): |
||||||
|
print("Done") |
||||||
|
return net |
||||||
|
|
||||||
|
if(expand): |
||||||
|
net, cubelen = expandCube(net, 1) |
||||||
|
newcube = net.copy() |
||||||
|
cubelen4 = net.shape[0] |
||||||
|
|
||||||
|
for iw in range(cubelen4): |
||||||
|
for iz in range(cubelen4): |
||||||
|
|
||||||
|
for iy in range(cubelen4): |
||||||
|
for ix in range(cubelen4): |
||||||
|
|
||||||
|
node = getpos4(ix, iy, iz, iw, net) |
||||||
|
activeCount, checkdCount = countaround4D(ix, iy, iz, iw, net) |
||||||
|
newnode = node |
||||||
|
|
||||||
|
if( node == 1 and not activeCount in [2, 3] ): |
||||||
|
newnode = 0 |
||||||
|
if( node == 0 and activeCount == 3 ): |
||||||
|
newnode = 1 |
||||||
|
|
||||||
|
setpos4(ix, iy, iz, iw, newnode, newcube) |
||||||
|
|
||||||
|
#print(f"{c=} : {ix=} {iy=} {iz=} {iw=} / {cubelen4=} : {checkdCount=} : {activeCount=} {node=} {newnode=} : {activeCount in [2,3]=}") |
||||||
|
#print("") |
||||||
|
|
||||||
|
|
||||||
|
# Print the new layers |
||||||
|
#print("orig", end=" ") |
||||||
|
#printLayer(iz, net) |
||||||
|
#print("new", end=" ") |
||||||
|
#printLayer(iz, newcube) |
||||||
|
|
||||||
|
#print(newcube) |
||||||
|
|
||||||
|
#print("New cycle\n") |
||||||
|
print(c, "/", maxc) |
||||||
|
net = newcube |
||||||
|
|
||||||
|
return runCycle4(net, c+1, expand=True) |
||||||
|
|
||||||
|
cube4, cubelen4 = expandCube(cube4, 2) |
||||||
|
endcube4 = runCycle4(cube4) |
||||||
|
print(endcube4) |
||||||
|
print( np.sum(endcube4) ) |
Loading…
Reference in new issue