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 C (judge verdict: Accepted)

#include<stdio.h>

#define M 4

typedef struct{
  int A[M][M];
}Pazzle;

Pazzle P;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};

int heuristic(Pazzle P){
  int i,j;
  int hx,hy,sum=0;

  for(i=0; i<M; i++){
    for(j=0; j<M; j++){
      if(P.A[i][j] == 0)continue;

      hx = (P.A[i][j]-1)%M-j;
      hy = (P.A[i][j]-1)/M-i;

      if(hx < 0)sum -= hx;
      else sum += hx;

      if(hy < 0)sum -= hy;
      else sum += hy;
    }
  }

  return sum;
}

int dfs(int x,int y,int max,int cnt,int n){
  int i,temp;
  int x0,y0,ans=-1,h;

  h = heuristic(P);

  if(h == 0)return cnt;
  if(cnt + h > max)return -1;

  for(i=0; i<4; i++){
    x0 = x + dx[i];
    y0 = y + dy[i];

    if((i == (n+2)%4 && n != -1) || !(0<=x0 && x0<M && 0<=y0 && y0<M))continue;
    temp = P.A[y][x];
    P.A[y][x] = P.A[y0][x0];
    P.A[y0][x0] = temp;

    ans = dfs(x0,y0,max,cnt+1,i);

    if(ans != -1)return ans;
    temp = P.A[y][x];
    P.A[y][x] = P.A[y0][x0];
    P.A[y0][x0] = temp;
  }

  return -1;
}

int main(){
  int i,j;
  int kx,ky,ans,a;
  Pazzle tP;

  for(i=0; i<M; i++){
    for(j=0; j<M; j++){
      scanf("%d",&a);
      P.A[i][j] = a;
      if(a == 0){
        kx = j;
        ky = i;
      }
    }
  }

  tP = P;

  for(i=1; i<46; i++){
    P=tP;
    ans = dfs(kx,ky,i,0,-1);
    if(ans != -1){
      printf("%d\n",ans);
      break;
    }
  }

  return 0;
}