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