My solutions for Advent of Code.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
adventofcode/2020/17.py

216 lines
5.1 KiB

#!/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
initlen = len(config[0])
print("Config:")
print(np.asarray(config))
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
cycles = 6
for iy in range(len(config)):
for ix in range(len(config)):
if(config[iy][ix] == "."):
cube[1][iy][ix] = 0
else:
cube[1][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("Part 1: Cube shape:", cube.shape)
print("Part 2: Hypercube shape:", 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 expandCube(net=cube, expand=1):
net = np.pad(net, pad_width=expand, mode='constant', constant_values=0)
cubelen = net.shape[0]
return net, cubelen
def runCycle(net, c=0, maxc=cycles, expand=False, ignoreCfgLayer=False):
if( not c < maxc ):
print("6 / 6 Done")
return net
if(expand):
net, cubelen = expandCube(net, 1)
newcube = net.copy()
cubelen = net.shape[0]
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( c, "/", maxc )
net = newcube
return runCycle(net, c+1, expand=True, ignoreCfgLayer=ignoreCfgLayer)
cycles = 6
def runCycle4(net, c=0, maxc=cycles, expand=False):
if( not c < maxc ):
print("6 / 6 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(c, "/", maxc)
net = newcube
return runCycle4(net, c+1, expand=True)
# Part 1
print("\nPart 1...")
cube, cubelen = expandCube(cube, 10)
endcube = runCycle(cube)
# Part 2
print("\nPart 2...")
cube4, cubelen4 = expandCube(cube4, 2)
endcube4 = runCycle4(cube4)
print("Part1:", np.sum(endcube))
print("Part2:", np.sum(endcube4))
print("\nAt least it is faster than compiling Firefox Kappa")