-
Notifications
You must be signed in to change notification settings - Fork 0
/
773. Sliding Puzzle.py
76 lines (66 loc) · 2.96 KB
/
773. Sliding Puzzle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import copy
import heapq
from collections import namedtuple
class Solution:
def slidingPuzzle(self, board: List[List[int]]) -> int:
def isGoalState(g, b):
r = len(b)
c = len(b[0])
for i in range(r):
for j in range(c):
if g[b[i][j]] != (i, j):
return False
return True
def calcHeuristic(goal_state, board):
ret = 0
r = len(board)
c = len(board[0])
for i in range(r):
for j in range(c):
ret += abs(goal_state[board[i][j]][0] - i) + abs(goal_state[board[i][j]][1] - j)
return ret
def mnPuzzle(board):
r = len(board)
c = len(board[0])
goal_state = {}
# Initialize goal_state dictionary with board indices (0 is last)
for i in range(r):
for j in range(c):
if r*c == c*i + j + 1:
goal_state[0] = (i, j)
continue
goal_state[c*i + j + 1] = (i, j)
State = namedtuple('State', ['total_cost', 'distance', 'board'])
heap = [State(0, 0, board)]
closed = []
while len(heap):
#print('iteration')
state = heapq.heappop(heap)
#print(state)
if isGoalState(goal_state, state.board):
return state.distance
else:
neighbours = []
# Find indices where '0' is
start = None
for i in range(r):
for j in range(c):
if state.board[i][j] == 0:
start = (i, j)
for offr, offc in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
if 0 <= start[0] + offr < r and 0 <= start[1] + offc < c:
n_board = copy.deepcopy(state.board)
n_board[start[0]+offr][start[1]+offc], n_board[start[0]][start[1]] = n_board[start[0]][start[1]], n_board[start[0]+offr][start[1]+offc]
#print("Generated neighbour: ", n_board)
neighbours.append(n_board)
for neighbour in neighbours:
if neighbour in closed:
continue
heapq.heappush(heap, State(state.distance + 1 + calcHeuristic(goal_state, neighbour), state.distance + 1, neighbour))
#print(neighbour)
#print(state.distance+1)
#print(calcHeuristic(goal_state, neighbour))
#print(state.distance+1+calcHeuristic(goal_state, neighbour))
closed.append(state.board)
return -1
return mnPuzzle(board)