13_cubicles.py 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. #!/usr/bin/env python3
  2. from heapq import heappush, heappop
  3. magic = 1350
  4. def popcount(n):
  5. count = 0
  6. while n:
  7. count += n & 1
  8. n >>= 1
  9. return count
  10. def is_space(x, y):
  11. return not popcount(x*x + 3*x + 2*x*y + y + y*y + magic) % 2
  12. def neighboring_spaces(x, y):
  13. if is_space(x + 1, y):
  14. yield x + 1, y
  15. if is_space(x, y + 1):
  16. yield x, y + 1
  17. if x > 0 and is_space(x - 1, y):
  18. yield x - 1, y
  19. if y > 0 and is_space(x, y - 1):
  20. yield x, y - 1
  21. def uniform_cost_search(source):
  22. frontier = [(0, source)]
  23. explored = {source}
  24. while frontier:
  25. dist, u = heappop(frontier)
  26. yield u, dist
  27. for v in neighboring_spaces(*u):
  28. if v not in explored:
  29. heappush(frontier, (dist + 1, v))
  30. explored.add(v)
  31. def shortest_path(source, dest):
  32. for node, dist in uniform_cost_search(source):
  33. if node == dest:
  34. return dist
  35. def reachable_in(source, maxdist):
  36. for count, (node, dist) in enumerate(uniform_cost_search(source)):
  37. if dist > maxdist:
  38. return count
  39. print(shortest_path((1, 1), (31, 39)))
  40. print(reachable_in((1, 1), 50))