23_teleport.py 1.0 KB

123456789101112131415161718192021222324252627282930313233343536
  1. #!/usr/bin/env python3
  2. import sys
  3. import re
  4. import z3
  5. from operator import itemgetter
  6. bots = [tuple(map(int, re.findall(r'-?[0-9]+', line))) for line in sys.stdin]
  7. # part 1
  8. x, y, z, r = max(bots, key=itemgetter(3))
  9. print(sum(int(abs(bx - x) + abs(by - y) + abs(bz - z) <= r)
  10. for bx, by, bz, br in bots))
  11. # part 2
  12. def zabs(x):
  13. return z3.If(x >= 0, x, -x)
  14. def dist(xa, ya, za, xb, yb, zb):
  15. return zabs(xb - xa) + zabs(yb - ya) + zabs(zb - za)
  16. # build an optimizing model with the solution and its intersections as variables
  17. x, y, z = z3.Ints('x y z')
  18. opt = z3.Optimize()
  19. # maximize: number of intersecting bots
  20. nisect = sum(z3.If(dist(bx, by, bz, x, y, z) <= br, 1, 0)
  21. for bx, by, bz, br in bots)
  22. bestisect = opt.maximize(nisect)
  23. # minimize: manhattan distance of solution to (0, 0, 0)
  24. bestdist = opt.minimize(dist(x, y, z, 0, 0, 0))
  25. assert opt.check() == z3.sat
  26. #print(opt.model())
  27. print('best teleportation point at %s from origin (%s nanobots in range)' %
  28. (bestdist.value(), bestisect.value()))