summary refs log tree commit diff stats
path: root/day22.py
blob: f2428da40240dd3455eb58b0a67bf7c4fd66a8e0 (plain) (blame)
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
#!/usr/bin/env python
import re
import numpy as np

coords_regex = re.compile(r'(\-?\d*)\.\.(\-?\d*)')
with open('day22.txt') as data:
    instructions = []
    for line in data:
        on, coords = line.strip().split()
        on = (on == 'on')
        coords = np.array(coords_regex.findall(coords), dtype=int)
        instructions.append((on, coords))


# part 1

reactor = np.zeros((101, 101, 101)).astype(bool)
for on, coords in instructions:
    coords = np.copy(coords)
    coords += 50
    if np.any(coords > 100) or np.any(coords < 0): break
    coords[:, 1] += 1
    coords = tuple(slice(start, stop) for start, stop in coords)
    reactor[coords] = on

print(np.count_nonzero(reactor))

# part 2
from collections import Counter

cubes = Counter()
for on, coords in instructions:
    nSign = 1 if on else -1
    nX0, nX1, nY0, nY1, nZ0, nZ1 = coords.flatten()

    update = Counter()
    for (eX0, eX1, eY0, eY1, eZ0, eZ1), eSign in cubes.items():
        iX0 = max(nX0, eX0); iX1 = min(nX1, eX1)
        iY0 = max(nY0, eY0); iY1 = min(nY1, eY1)
        iZ0 = max(nZ0, eZ0); iZ1 = min(nZ1, eZ1)
        if iX0 < iX1 and iY0 < iY1 and iZ0 < iZ1:
            update[(iX0, iX1, iY0, iY1, iZ0, iZ1)] -= eSign
    
    if nSign > 0:
        update[(nX0, nX1, nY0, nY1, nZ0, nZ1)] += nSign
    cubes.update(update)
print(sum((x1-x0+1)*(y1-y0+1)*(z1-z0+1)*sgn
        for (x0, x1, y0, y1, z0, z1), sgn in cubes.items()))