Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from Queue import heapq as hq
- from copy import deepcopy
- k, N, goal = [None] * 3
- class State:
- def __init__(self, sig):
- self.sig = deepcopy(sig)
- for i in xrange(N):
- if self.sig[i] == 0:
- self.pos0 = i
- break
- self.h = self.__heuristic__()
- self.str = self.__toStr__()
- def __toStr__(self):
- return reduce(lambda x, y: x + str(y), self.sig, '')
- def __str__(self):
- return self.str
- # Goal configuration [0, 1, ..., k*k-1] has been hardcoded
- # to get an efficient implementation
- def __moveCount__(self, i):
- if self.sig[i] == 0:
- return 0
- return abs((i / k) - (self.sig[i] / k)) + abs((i % k) - (self.sig[i] % k))
- def __heuristic__(self):
- return reduce(lambda x, y: x + self.__moveCount__(y), xrange(N), 0)
- # Manhattan distance
- def heuristic(self):
- return self.h
- def moves(self):
- candidates = []
- copy = deepcopy(self.sig)
- if self.pos0 >= k:
- copy[self.pos0], copy[self.pos0 - k] = copy[self.pos0 - k], copy[self.pos0]
- candidates.append([State(copy), 'U'])
- copy[self.pos0], copy[self.pos0 - k] = copy[self.pos0 - k], copy[self.pos0]
- if self.pos0 < N-k:
- copy[self.pos0], copy[self.pos0 + k] = copy[self.pos0 + k], copy[self.pos0]
- candidates.append([State(copy), 'D'])
- copy[self.pos0], copy[self.pos0 + k] = copy[self.pos0 + k], copy[self.pos0]
- if (self.pos0 % k) > 0:
- copy[self.pos0], copy[self.pos0 - 1] = copy[self.pos0 - 1], copy[self.pos0]
- candidates.append([State(copy), 'L'])
- copy[self.pos0], copy[self.pos0 - 1] = copy[self.pos0 - 1], copy[self.pos0]
- if (self.pos0 % k) < k-1:
- copy[self.pos0], copy[self.pos0 + 1] = copy[self.pos0 + 1], copy[self.pos0]
- candidates.append([State(copy), 'R'])
- copy[self.pos0], copy[self.pos0 + 1] = copy[self.pos0 + 1], copy[self.pos0]
- return candidates
- def isGoal(self):
- return self.sig == goal
- def astar(start):
- pq = []
- closed = set()
- hq.heappush(pq, [start.heuristic(), 0, start, []])
- while pq:
- f, g, cur, path = hq.heappop(pq)
- if cur.isGoal():
- return g, path
- closed.add(str(cur))
- for child, move in cur.moves():
- if str(child) not in closed:
- p = deepcopy(path)
- p.append(move)
- hq.heappush(pq, [g+1 + child.heuristic(), g+1, child, p])
- return None
- if __name__ == "__main__":
- k = int(raw_input())
- N = k * k
- pattern = [int(raw_input()) for i in xrange(N)]
- goal = [i for i in xrange(N)]
- count, path = astar(State(pattern))
- moves = {'U':'UP', 'D':'DOWN', 'L':'LEFT', 'R':'RIGHT'}
- print count
- for move in path:
- print moves[move]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement