23_teleport.py 1.1 KB

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