18_voxels.py 1.0 KB

123456789101112131415161718192021222324252627282930313233343536
  1. #!/usr/bin/env python3
  2. import sys
  3. def neighbors(x, y, z):
  4. yield x - 1, y, z
  5. yield x + 1, y, z
  6. yield x, y - 1, z
  7. yield x, y + 1, z
  8. yield x, y, z - 1
  9. yield x, y, z + 1
  10. def total_surface(voxels):
  11. return sum(nb not in voxels for xyz in voxels for nb in neighbors(*xyz))
  12. def exterior_surface(voxels):
  13. w = max(x for x, _, _ in voxels) + 1
  14. h = max(y for _, y, _ in voxels) + 1
  15. d = max(z for _, _, z in voxels) + 1
  16. outside = {(-1, -1, -1)}
  17. visit = list(outside)
  18. while visit:
  19. for nb in neighbors(*visit.pop()):
  20. nx, ny, nz = nb
  21. if -1 <= nx <= w and -1 <= ny <= h and -1 <= nz <= d \
  22. and nb not in outside and nb not in voxels:
  23. outside.add(nb)
  24. visit.append(nb)
  25. filled = {(x, y, z) for x in range(w) for y in range(h)
  26. for z in range(d) if (x, y, z) not in outside}
  27. return total_surface(filled)
  28. voxels = {tuple(map(int, line.split(','))) for line in sys.stdin}
  29. print(total_surface(voxels))
  30. print(exterior_surface(voxels))