13_cubicles.py 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  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. count = 0
  37. for node, dist in uniform_cost_search(source):
  38. if dist > maxdist:
  39. return count
  40. count += 1
  41. print(shortest_path((1, 1), (31, 39)))
  42. print(reachable_in((1, 1), 50))