18.py 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. from queue import PriorityQueue
  2. droplet = {tuple(map(int,line.split(","))) for line in open("18.input")}
  3. NBRS = [
  4. (1, 0, 0),
  5. (-1, 0, 0),
  6. (0, 1, 0),
  7. (0, -1, 0),
  8. (0, 0, 1),
  9. (0, 0,-1),
  10. ]
  11. def add(a, b):
  12. return (a[0] + b[0], a[1] + b[1], a[2] + b[2])
  13. def nbr_cnt(pos, points):
  14. return sum(1 for nbr in NBRS if add(pos, nbr) in points)
  15. def surface_of(bleh):
  16. return sum(6 - nbr_cnt(pos, bleh) for pos in bleh)
  17. total_surface = surface_of(droplet)
  18. print("Part 1:", total_surface)
  19. dims = [(min(itr), max(itr)) for itr in [[p[i] for p in droplet] for i in range(3)]]
  20. bounds = {(x, y, z) for x in range(dims[0][0] - 1, dims[0][1] + 2) for y in range(dims[1][0] - 1, dims[1][1] + 2) for z in range(dims[2][0] - 1, dims[2][1] + 2)}
  21. def search_connected(start, include, exclude):
  22. q = PriorityQueue()
  23. result = set()
  24. result.add(start)
  25. q.put(start)
  26. while not q.empty():
  27. pos = q.get()
  28. for n in NBRS:
  29. p = add(pos, n)
  30. if p not in include:
  31. continue
  32. if p in exclude:
  33. continue
  34. if p in result:
  35. continue
  36. result.add(p)
  37. q.put(p)
  38. return result
  39. exterior = search_connected((0,0,0), bounds, droplet)
  40. interior = (bounds - exterior - droplet)
  41. interior_surface = surface_of(interior)
  42. print("Part 2:", total_surface - interior_surface)