day18 almost
This commit is contained in:
parent
6c482630c2
commit
5e8b272801
@ -4,6 +4,11 @@ from pprint import pprint
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Set, Tuple
|
from typing import Set, Tuple
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
|
from mpl_toolkits.mplot3d import Axes3D
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -31,12 +36,24 @@ def get_neighbors(x,y,z):
|
|||||||
(0,0,-1),# 5
|
(0,0,-1),# 5
|
||||||
(-1,0,0) # 6
|
(-1,0,0) # 6
|
||||||
)
|
)
|
||||||
neighbor_coords = set([(x+o[0], y+o[1], z+o[2]) for o in offsets])
|
return set([(x+o[0], y+o[1], z+o[2]) for o in offsets])
|
||||||
return neighbor_coords
|
|
||||||
|
|
||||||
def count_neighbor_coords(x,y,z):
|
def get_flat_neighbors(x,y,z):
|
||||||
pass
|
# Generate the six neighbor_coords
|
||||||
|
# Look at a die 6 to the left, 2 on top, one on right
|
||||||
|
# ignore top and bottom
|
||||||
|
offsets = (
|
||||||
|
(1,0,0), # 1
|
||||||
|
#(0,0,1), # 2
|
||||||
|
(0,-1,0),# 3
|
||||||
|
(0,1,0), # 4
|
||||||
|
#(0,0,-1),# 5
|
||||||
|
(-1,0,0) # 6
|
||||||
|
)
|
||||||
|
return set([(x+o[0], y+o[1], z+o[2]) for o in offsets])
|
||||||
|
|
||||||
|
def get_flat_neighbors_from(x,y,z, f):
|
||||||
|
return get_flat_neighbors(x,y,z).intersection(f)
|
||||||
|
|
||||||
|
|
||||||
# @shared.profile
|
# @shared.profile
|
||||||
@ -53,7 +70,7 @@ def part1(rows):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def part2(rows):
|
def surface_area(rows):
|
||||||
cubes = {}
|
cubes = {}
|
||||||
maxX,maxY,maxZ = 0,0,0
|
maxX,maxY,maxZ = 0,0,0
|
||||||
for idx, (x,y,z) in enumerate(rows):
|
for idx, (x,y,z) in enumerate(rows):
|
||||||
@ -68,77 +85,92 @@ def part2(rows):
|
|||||||
for other in cube['not_me']:
|
for other in cube['not_me']:
|
||||||
if other in cube['n']:
|
if other in cube['n']:
|
||||||
potential -= 1
|
potential -= 1
|
||||||
|
return potential, maxX,maxY,maxZ, cubes, _cubes
|
||||||
|
|
||||||
|
|
||||||
|
def part2(rows):
|
||||||
|
potential, maxX, maxY,maxZ,cubes,_cubes = surface_area(rows)
|
||||||
|
|
||||||
|
|
||||||
air = set()
|
air = set()
|
||||||
for x in range(0,maxX+1):
|
for x in range(0,maxX+1):
|
||||||
for y in range(0,maxY+1):
|
for y in range(0,maxY+1):
|
||||||
for z in range(0,maxZ+1):
|
for z in range(0,maxZ+1):
|
||||||
air.add((x,y,z))
|
if (x,y,z) not in _cubes:
|
||||||
|
air.add((x,y,z))
|
||||||
air -= _cubes # Remove all lava from air
|
air -= _cubes # Remove all lava from air
|
||||||
|
all_air_count = len(air)
|
||||||
|
all_lava_count = len(_cubes)
|
||||||
|
possible_count = (maxX+1)*(maxY+1)*(maxZ+1)
|
||||||
|
|
||||||
|
print("all_air: ", all_air_count)
|
||||||
|
print("all_lava:", all_lava_count)
|
||||||
|
print("possible:", possible_count)
|
||||||
|
print(maxZ,maxY,maxX)
|
||||||
|
print()
|
||||||
|
|
||||||
|
air_nx = {}
|
||||||
for a in air:
|
for a in air:
|
||||||
neighbors = get_neighbors(*a)
|
neighbors = get_neighbors(*a)
|
||||||
if len(neighbors & _cubes)==6:
|
air_nx[a] = {
|
||||||
#print(a, "====", neighbors & _cubes)
|
'lava':neighbors & _cubes or None,
|
||||||
potential -= 6
|
'air': neighbors & air or None
|
||||||
|
}
|
||||||
|
|
||||||
|
# loop row by row
|
||||||
# _ns = get_neighbors(x,y,z)
|
inside = []
|
||||||
# lava_neighbors = _ns & _cubes
|
for z in range(0,maxZ+1):
|
||||||
# if len(lava_neighbors) == 6:
|
seen = set()
|
||||||
# potential -= 6
|
seen.add((0,0,z))
|
||||||
print(potential)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# @shared.profile
|
|
||||||
def _part2(rows):
|
|
||||||
cubes = []
|
|
||||||
|
|
||||||
_lava = set()
|
|
||||||
for row in rows:
|
|
||||||
x,y,z = row
|
|
||||||
maxX = max(maxX,x)
|
|
||||||
maxY = max(maxY,y)
|
|
||||||
maxZ = max(maxZ,z)
|
|
||||||
cube = Cube(x=x,y=y,z=z)
|
|
||||||
cube.set_neighbor_coords()
|
|
||||||
cubes.append(cube)
|
|
||||||
_lava.add((x,y,z))
|
|
||||||
print(maxX,maxY,maxZ)
|
|
||||||
|
|
||||||
potential = len(cubes) * 6
|
|
||||||
for idx in range(len(cubes)):
|
|
||||||
cube = cubes[idx]
|
|
||||||
others = cubes[:idx] + cubes[idx+1:]
|
|
||||||
for other in others:
|
|
||||||
if other.xyz in cube.neighbor_coords:
|
|
||||||
potential -= 1
|
|
||||||
|
|
||||||
|
|
||||||
air = []
|
|
||||||
for x in range(0,maxX+1):
|
|
||||||
for y in range(0,maxY+1):
|
for y in range(0,maxY+1):
|
||||||
for z in range(0,maxZ+1):
|
for x in range(0,maxX+1):
|
||||||
lava_count = 0
|
xyz = (x,y,z)
|
||||||
if (x,y,z) in _lava:
|
if xyz in _cubes:
|
||||||
|
#print(xyz,'is cube')
|
||||||
continue
|
continue
|
||||||
|
ns = get_flat_neighbors_from(x,y,z, air)
|
||||||
|
for neigh in ns:
|
||||||
|
if neigh in seen and neigh not in _cubes:
|
||||||
|
seen.add(xyz)
|
||||||
|
this_level = air_in_row(air, z)
|
||||||
|
print(this_level, seen)
|
||||||
|
print(len(this_level), len(seen))
|
||||||
|
inside.extend([x for x in this_level if x not in seen])
|
||||||
|
#print()
|
||||||
|
#print(inside)
|
||||||
|
#print()
|
||||||
|
actually_inside = []
|
||||||
|
for i in inside:
|
||||||
|
ns = get_neighbors(*i)
|
||||||
|
# check for surrounded 100% by rock
|
||||||
|
rock_count = 0
|
||||||
|
for n in ns:
|
||||||
|
if n in _cubes:
|
||||||
|
rock_count +=1
|
||||||
|
if rock_count == 6:
|
||||||
|
print("in rock")
|
||||||
|
actually_inside.append(i)
|
||||||
|
continue
|
||||||
|
#check for surrounded 100% by air
|
||||||
|
air_count = 0
|
||||||
|
for n in ns:
|
||||||
|
if n in air:
|
||||||
|
air_count +=1
|
||||||
|
print("in air")
|
||||||
|
break
|
||||||
|
actually_inside.append(i)
|
||||||
|
#print(actually_inside)
|
||||||
|
tot, _, _, _, _, _ = surface_area(actually_inside)
|
||||||
|
print(tot)
|
||||||
|
print(potential - tot)
|
||||||
|
shared.render_cubes(maxX,maxY,maxZ, [x for x in actually_inside])
|
||||||
|
|
||||||
# is air
|
def air_in_row(air, z):
|
||||||
air_touching_lava = False
|
x = []
|
||||||
for _n in _ns:
|
for a in air:
|
||||||
if _n in _lava:
|
if a[2] == z:
|
||||||
lava_count += 1
|
x.append(a)
|
||||||
air_touching_lava = True
|
return x
|
||||||
|
|
||||||
if air_touching_lava:
|
|
||||||
air.append((x,y,z))
|
|
||||||
|
|
||||||
if lava_count == 6:
|
|
||||||
potential -= 6
|
|
||||||
|
|
||||||
|
|
||||||
print(potential, air)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,3 +102,60 @@ def elapsed_timer():
|
|||||||
yield lambda: elapser()
|
yield lambda: elapser()
|
||||||
end = default_timer()
|
end = default_timer()
|
||||||
elapser = lambda: end - start
|
elapser = lambda: end - start
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def render_cubes(maxX,maxY,maxZ, my_cubes):
|
||||||
|
from mpl_toolkits.mplot3d import Axes3D
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
|
||||||
|
|
||||||
|
def cuboid_data(o, size=(1,1,1)):
|
||||||
|
X = [[[0, 1, 0], [0, 0, 0], [1, 0, 0], [1, 1, 0]],
|
||||||
|
[[0, 0, 0], [0, 0, 1], [1, 0, 1], [1, 0, 0]],
|
||||||
|
[[1, 0, 1], [1, 0, 0], [1, 1, 0], [1, 1, 1]],
|
||||||
|
[[0, 0, 1], [0, 0, 0], [0, 1, 0], [0, 1, 1]],
|
||||||
|
[[0, 1, 0], [0, 1, 1], [1, 1, 1], [1, 1, 0]],
|
||||||
|
[[0, 1, 1], [0, 0, 1], [1, 0, 1], [1, 1, 1]]]
|
||||||
|
X = np.array(X).astype(float)
|
||||||
|
for i in range(3):
|
||||||
|
X[:,:,i] *= size[i]
|
||||||
|
X += np.array(o)
|
||||||
|
return X
|
||||||
|
|
||||||
|
def plotCubeAt(positions,sizes=None,colors=None, **kwargs):
|
||||||
|
if not isinstance(colors,(list,np.ndarray)): colors=["C0"]*len(positions)
|
||||||
|
if not isinstance(sizes,(list,np.ndarray)): sizes=[(1,1,1)]*len(positions)
|
||||||
|
g = []
|
||||||
|
for p,s,c in zip(positions,sizes,colors):
|
||||||
|
g.append( cuboid_data(p, size=s) )
|
||||||
|
return Poly3DCollection(np.concatenate(g),
|
||||||
|
facecolors=np.repeat(colors,6, axis=0), **kwargs)
|
||||||
|
|
||||||
|
N1 = maxX
|
||||||
|
N2 = maxY
|
||||||
|
N3 = maxZ
|
||||||
|
ma = np.random.choice([0,1], size=(N1,N2,N3), p=[0.99, 0.01])
|
||||||
|
x,y,z = np.indices((N1,N2,N3))-.5
|
||||||
|
#positions = np.c_[x[ma==1],y[ma==1],z[ma==1]]
|
||||||
|
positions = np.c_[my_cubes]
|
||||||
|
colors= np.random.rand(len(positions),3)
|
||||||
|
|
||||||
|
fig = plt.figure()
|
||||||
|
ax = fig.add_subplot(projection='3d')
|
||||||
|
ax.set_aspect('equal')
|
||||||
|
|
||||||
|
pc = plotCubeAt(positions, colors=colors,edgecolor="k")
|
||||||
|
ax.add_collection3d(pc)
|
||||||
|
|
||||||
|
ax.set_xlim([0,maxX])
|
||||||
|
ax.set_ylim([0,maxY])
|
||||||
|
ax.set_zlim([0,maxZ])
|
||||||
|
#plotMatrix(ax, ma)
|
||||||
|
#ax.voxels(ma, edgecolor="k")
|
||||||
|
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user