Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

3 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. from itertools import combinations, product
  2. def manhattan(p1, p2):
  3. return tuple(abs(a - b) for a, b in zip(p1, p2))
  4. def find_shared_transpose(pts):
  5. new = {manhattan(a, b): a for a, b in combinations(pts, 2)}
  6. deltas = [
  7. [(a - b) for a, b in zip(constellations[k], new[k])]
  8. for k in set(constellations) & set(new)
  9. ]
  10. if deltas:
  11. return [max(t, key=t.count) for t in zip(*deltas)]
  12. def overlap(pts):
  13. for fx, fy, fz in product([1, -1], [1, -1], [1, -1]):
  14. flipped = {(x * fx, y * fy, z * fz) for x, y, z in pts}
  15. if deltas := find_shared_transpose(flipped):
  16. dx, dy, dz = deltas
  17. transposed = {(x + dx, y + dy, z + dz) for x, y, z in flipped}
  18. if len(all_beacons & transposed) >= 12:
  19. update_state((-dx, -dy, -dz), transposed)
  20. return True
  21. def update_state(scanner, beacons):
  22. all_scanners.add(scanner)
  23. all_beacons.update(beacons)
  24. new = {manhattan(a, b): a for a, b in combinations(all_beacons, 2)}
  25. constellations.update(new)
  26. def transform(step, pts):
  27. if step % 3 == 0:
  28. pts = [pt[::-1] for pt in pts]
  29. return [pt[1:] + pt[:1] for pt in pts]
  30. text = open(0).read()
  31. reference, *readings = [
  32. [tuple(int(n) for n in ln.split(',')) for ln in scnr.splitlines()[1:]]
  33. for scnr in text.split('\n\n')
  34. ]
  35. all_scanners = set()
  36. all_beacons = set()
  37. constellations = {}
  38. update_state((0, 0, 0), reference)
  39. for step in range(30):
  40. readings = [transform(step, pts) for pts in readings if not overlap(pts)]
  41. print(len(all_beacons))
  42. print(max(sum(manhattan(a, b)) for a, b in combinations(all_scanners, 2)))