Day 17, any dimensions you want!
This commit is contained in:
parent
ae2ddfc742
commit
94f8d2f443
|
@ -1,18 +1,20 @@
|
||||||
import sys
|
import sys
|
||||||
|
from itertools import product
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
lines = [line.rstrip() for line in sys.stdin]; sys.stdin = open("/dev/tty")
|
lines = [line.rstrip() for line in sys.stdin]
|
||||||
|
|
||||||
print("Actives:", part1(lines))
|
print("Actives:", solve(lines, 3))
|
||||||
print("Hyperactives:", part2(lines))
|
print("Hyperactives:", solve(lines, 4))
|
||||||
|
|
||||||
|
|
||||||
def part1(lines):
|
def solve(lines, dimensions):
|
||||||
s = {}
|
s = {}
|
||||||
for y, line in enumerate(lines):
|
for y, line in enumerate(lines):
|
||||||
for x, c in enumerate(line):
|
for x, c in enumerate(line):
|
||||||
s[(x, y, 0)] = 1 if c == "#" else 0
|
p = (x, y) + (0,) * (dimensions - 2)
|
||||||
|
s[p] = 1 if c == "#" else 0
|
||||||
for _ in range(6):
|
for _ in range(6):
|
||||||
cycle(s)
|
cycle(s)
|
||||||
return sum(s.values())
|
return sum(s.values())
|
||||||
|
@ -20,59 +22,25 @@ def part1(lines):
|
||||||
|
|
||||||
def cycle(s):
|
def cycle(s):
|
||||||
future = {}
|
future = {}
|
||||||
work_set = set(nn for x, y, z in s for nn in near(x, y, z))
|
work_set = set(nn for pos in s for nn in near(*pos))
|
||||||
for x, y, z in work_set:
|
for pos in work_set:
|
||||||
an = 0
|
an = 0
|
||||||
for nn in near(x, y, z):
|
for nn in near(*pos):
|
||||||
an += s.get(nn, 0)
|
an += s.get(nn, 0)
|
||||||
if (v := s.get((x, y, z), 0)) == 1 and not 2 <= an <= 3:
|
if (v := s.get(pos, 0)) == 1 and not 2 <= an <= 3:
|
||||||
future[(x, y, z)] = 0
|
future[pos] = 0
|
||||||
elif v == 0 and an == 3:
|
elif v == 0 and an == 3:
|
||||||
future[(x, y, z)] = 1
|
future[pos] = 1
|
||||||
for f, fv in future.items():
|
for f, fv in future.items():
|
||||||
s[f] = fv
|
s[f] = fv
|
||||||
|
|
||||||
|
|
||||||
def near(x, y, z, include_self=False):
|
def near(*comp):
|
||||||
for zi in range(-1, 2):
|
num_comp = len(comp)
|
||||||
for yi in range(-1, 2):
|
offsets = list(product([-1, 0, 1], repeat=num_comp))
|
||||||
for xi in range(-1, 2):
|
offsets.remove((0,) * num_comp)
|
||||||
if include_self or xi != 0 or yi != 0 or zi != 0:
|
for p in offsets:
|
||||||
yield x + xi, y + yi, z + zi
|
yield tuple(c + o for c, o in zip(comp, p))
|
||||||
|
|
||||||
|
|
||||||
def part2(lines):
|
|
||||||
h = {}
|
|
||||||
for y, line in enumerate(lines):
|
|
||||||
for x, c in enumerate(line):
|
|
||||||
h[(x, y, 0, 0)] = 1 if c == "#" else 0
|
|
||||||
for _ in range(6):
|
|
||||||
cycle2(h)
|
|
||||||
return sum(h.values())
|
|
||||||
|
|
||||||
|
|
||||||
def cycle2(h):
|
|
||||||
future = {}
|
|
||||||
work_set = set(nn for x, y, z, w in h for nn in hyper_near(x, y, z, w))
|
|
||||||
for x, y, z, w in work_set:
|
|
||||||
an = 0
|
|
||||||
for nn in hyper_near(x, y, z, w):
|
|
||||||
an += h.get(nn, 0)
|
|
||||||
if (v := h.get((x, y, z, w), 0)) == 1 and not 2 <= an <= 3:
|
|
||||||
future[(x, y, z, w)] = 0
|
|
||||||
elif v == 0 and an == 3:
|
|
||||||
future[(x, y, z, w)] = 1
|
|
||||||
for f, fv in future.items():
|
|
||||||
h[f] = fv
|
|
||||||
|
|
||||||
|
|
||||||
def hyper_near(x, y, z, w, include_self=False): # oh boy
|
|
||||||
for wi in range(-1, 2):
|
|
||||||
for zi in range(-1, 2):
|
|
||||||
for yi in range(-1, 2):
|
|
||||||
for xi in range(-1, 2):
|
|
||||||
if include_self or xi != 0 or yi != 0 or zi != 0 or wi != 0:
|
|
||||||
yield x + xi, y + yi, z + zi, w + wi
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in a new issue