17_cubes.py 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. #!/usr/bin/env python3
  2. import sys
  3. from collections import defaultdict
  4. def parse(f):
  5. for y, line in enumerate(f):
  6. for x, cube in enumerate(line.rstrip()):
  7. if cube == '#':
  8. yield x, y, 0, 0
  9. def neighbors(coord, extra_dim):
  10. x, y, z, w = coord
  11. for dx in (-1, 0, 1):
  12. for dy in (-1, 0, 1):
  13. for dz in (-1, 0, 1):
  14. for dw in (-1, 0, 1) if extra_dim else (0,):
  15. if dx or dy or dz or dw:
  16. yield x + dx, y + dy, z + dz, w + dw
  17. def changes(active, extra_dim):
  18. inactive = defaultdict(int)
  19. for coord in active:
  20. active_nbs = 0
  21. for nb in neighbors(coord, extra_dim):
  22. if nb in active:
  23. active_nbs += 1
  24. else:
  25. inactive[nb] += 1
  26. if active_nbs not in (2, 3):
  27. yield coord, False
  28. for coord, active_nbs in inactive.items():
  29. if active_nbs == 3:
  30. yield coord, True
  31. def cycle(active, n, extra_dim):
  32. active = set(active)
  33. for i in range(n):
  34. for coord, activate in list(changes(active, extra_dim)):
  35. (active.add if activate else active.remove)(coord)
  36. return len(active)
  37. active = list(parse(sys.stdin))
  38. print(cycle(active, 6, False))
  39. print(cycle(active, 6, True))