Advertisement
Guest User

Untitled

a guest
Mar 28th, 2017
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.01 KB | None | 0 0
  1. from collections import defaultdict
  2. import itertools as it
  3.  
  4. def _rebuild_path(path_map, end):
  5. path = [end]
  6. current_source = path_map[end]
  7. while current_source is not None:
  8. path.insert(0, current_source)
  9. current_source = path_map[current_source]
  10. return path
  11.  
  12. def dijkstra(source, is_end):
  13. to_visit = set([source])
  14. came_from = defaultdict(lambda: None)
  15. dist_to = defaultdict(lambda: float('inf'))
  16. dist_to[source] = 0
  17. while to_visit:
  18. vertex = min(to_visit, key=lambda v: dist_to[v])
  19. to_visit.remove(vertex)
  20. local_print(vertex)
  21. if is_end(vertex):
  22. return _rebuild_path(came_from, end)
  23. for n_vertex in neighbors(vertex):
  24. alt = dist_to[vertex] + 1
  25. if dist_to[n_vertex] is None or alt < dist_to[n_vertex]:
  26. dist_to[n_vertex] = alt
  27. came_from[n_vertex] = vertex
  28.  
  29. N = int(input())
  30. M = []
  31. for _ in range(N):
  32. M.append(list(input()))
  33.  
  34. local_print("N = %s" % N)
  35.  
  36. DIRECTIONS = {
  37. 'North': (0, -1), 'South': (0, 1),
  38. 'East': (1, 0), 'West': (-1, 0),
  39. }
  40.  
  41. start = None
  42. ghosts = []
  43. for x, y in it.product(range(N), range(N)):
  44. v = M[x][y]
  45. if v == 'C':
  46. start = (x, y)
  47. M[x][y] = '.'
  48. elif v == 'M':
  49. ghosts.append((x, y))
  50. M[x][y] = '.'
  51. elif v == 'O':
  52. past = (x, y)
  53.  
  54. start = start, tuple(ghosts)
  55. del ghosts
  56.  
  57. def in_bounds(x, y):
  58. r = 0 <= x < N and 0 <= y < N
  59. #local_print("in_bounds(%s, %s) = %s" % (x, y, r))
  60. return r
  61.  
  62. def is_wall(x, y):
  63. r = M[x][y] == '#'
  64. #local_print("is_wall(%s, %s) = %s" % (x, y, r))
  65. return r
  66.  
  67. def can_move_to(x, y):
  68. r = in_bounds(x, y) and not is_wall(x, y)
  69. #local_print("can_move_to(%s, %s) = %s" % (x, y, r))
  70. return r
  71.  
  72. def move_pos(pos, diff):
  73. x, y = pos
  74. dx, dy = diff
  75. nx, ny = (x + dx, y + dy)
  76. if nx < 0:
  77. nx = N - 1
  78. elif nx == N:
  79. nx = 0
  80. return nx, ny
  81.  
  82. def all_ghost_moves(ghosts):
  83. all_moves = map(lambda x: (x[0][0], move_pos(x[0][1], x[1])), it.product(enumerate(ghosts), DIRECTIONS.values()))
  84. valid_moves = list(filter(lambda p: can_move_to(p[1][0], p[1][1]), all_moves))
  85. #local_print("valid_moves: %s" % (valid_moves,))
  86. groups = map(lambda x: x[1], it.groupby(valid_moves, key=lambda x: x[0]))
  87. return map(lambda x: map(tuple, x[1]), it.product(*groups))
  88.  
  89. def neighbors(node):
  90. pos, ghosts = node
  91. x, y = pos
  92. for direction in DIRECTIONS.values():
  93. nx, ny = move_pos(pos, direction)
  94. if not can_move_to(nx, ny):
  95. continue
  96. local_print("can_move_to: %s" % ((nx, ny),))
  97. for new_ghosts in all_ghost_moves(ghosts):
  98. local_print("new_ghosts: %s" % (new_ghosts,))
  99. if pos in new_ghosts:
  100. continue
  101. yield pos, new_ghosts
  102.  
  103. local_print("start: %s" % (start,))
  104. search = dijkstra(start, lambda pg: pg[0] == past)
  105. print(len(search))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement