Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

15 Puzzle

The goal of the 15 puzzle problem is to complete pieces on $4 \times 4$ cells where one of the cells is empty space.

In this problem, the space is represented by 0 and pieces are represented by integers from 1 to 15 as shown below.

1 2 3 4
6 7 8 0
5 10 11 12
9 13 14 15

You can move a piece toward the empty space at one step. Your goal is to make the pieces the following configuration in the shortest move (fewest steps).

1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 0

Write a program which reads an initial state of the puzzle and prints the fewest steps to solve the puzzle.

Input

The $4 \times 4$ integers denoting the pieces or space are given.

Output

Print the fewest steps in a line.

Constraints

The given puzzle is solvable in at most 45 steps.

Sample Input

1 2 3 4
6 7 8 0
5 10 11 12
9 13 14 15

Sample Output

8

Solution in Python3 (judge verdict: Time Limit Exceeded)

from collections import deque
import copy
def move(P,r,c):
    if r > 0:
        tmp = copy.deepcopy(P)
        tmp[r][c],tmp[r-1][c] = tmp[r-1][c],tmp[r][c]
        tmpr = r - 1
        yield tmp,tmpr,c
    if r < 3:
        tmp = copy.deepcopy(P)
        tmp[r][c],tmp[r+1][c] = tmp[r+1][c],tmp[r][c]
        tmpr = r + 1
        yield tmp,tmpr,c
    if c > 0:
        tmp = copy.deepcopy(P)
        tmp[r][c],tmp[r][c-1] = tmp[r][c-1],tmp[r][c]
        tmpc = c - 1
        yield tmp,r,tmpc
    if c < 3:
        tmp = copy.deepcopy(P)
        tmp[r][c],tmp[r][c+1] = tmp[r][c+1],tmp[r][c]
        tmpc = c + 1
        yield tmp,r,tmpc

A = [[int(i) for i in input().split()] for _ in range(4)]
for i in range(4):
        for j in range(4):
            if A[i][j] == 0:
                r,c = i,j
dp = {str(A) : 1}
d = deque([(A,0,r,c)])
flag = True
while(flag):
    tmp,count,r,c = d.pop()
    for i,j,k in move(tmp,r,c):
        key = str(i)
        if key in dp:
            continue
        elif key == "[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 0]]":
            ans = count + 1
            flag = False
        else:
            dp[key] = 1
            d.appendleft((i,count+1,j,k))
if str(A) == "[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 0]]":
    ans = 0
print(ans)