1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
data = open("day22data.txt").read().splitlines()
dims = {"x": 0, "y": 1, "z": 2}
class Cubes:
def __init__(self, limits, state):
self.state = state
self.limits = limits
self.corners = set()
for x in limits["x"]:
for y in limits["y"]:
for z in limits["z"]:
self.corners.add((x, y, z))
self.removed = []
def inside(self, point):
for dim in self.limits:
if (
self.limits[dim][0] > point[dims[dim]]
or self.limits[dim][1] < point[dims[dim]]
):
return False
return True
def combineWith(self, other):
overlapLimits = self.overlap(other)
if overlapLimits:
self.removeCube(Cubes(overlapLimits, "off"))
return True
else:
return False
def removeCube(self, other):
for rem in self.removed:
rem.combineWith(other)
self.removed.append(other)
def overlap(self, other):
overlapLimits = {}
for dim in self.limits:
thisMin = self.limits[dim][0]
thisMax = self.limits[dim][1]
otherMin = other.limits[dim][0]
otherMax = other.limits[dim][1]
overlapMin = max(thisMin, otherMin)
overlapMax = min(thisMax, otherMax)
if overlapMin <= overlapMax:
overlapLimits[dim] = [overlapMin, overlapMax]
else:
return None
return overlapLimits
def volume(self):
vol = 1
for dim in self.limits:
vol *= self.limits[dim][1] - self.limits[dim][0] + 1
removedVol = 0
for rem in self.removed:
removedVol += rem.volume()
return vol - removedVol
cubes = {}
cubesA = {}
cubeA = Cubes({"x": [-50, 50], "y": [-50, 50], "z": [-50, 50]}, "A")
id = 0
idA = 0
for rule in data:
state, poses = rule.split()
poses = [x.split("=") for x in poses.split(",")]
vals = {}
for pos in poses:
vals[pos[0]] = [int(x) for x in pos[1].split("..")]
newCube = Cubes(vals, state)
overlapA = cubeA.overlap(newCube)
if overlapA:
newCubeA = Cubes(overlapA, state)
for j in range(idA):
cubesA[j].combineWith(newCubeA)
if state == "on":
cubesA[idA] = newCubeA
idA += 1
for i in range(id):
cubes[i].combineWith(newCube)
if state == "on":
cubes[id] = newCube
id += 1
totVolA = 0
for c in cubesA:
totVolA += cubesA[c].volume()
totVol = 0
for c in cubes:
totVol += cubes[c].volume()
print(totVolA)
print(totVol)
|