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>
#include<stdlib.h>
#include<string.h>

#define N 4
#define M 46

int A[N][N]={
  {1,2,3,4},
  {5,6,7,8},
  {9,10,11,12},
  {13,14,15,0}};
  
int P[N*N]={3,0,1,2,
	    3,0,1,2,
	    3,0,1,2,
	    3,0,1,2},Q[N*N]={3,0,0,0,
	    0,1,1,1,
	    1,2,2,2,
	    2,3,3,3};

int min=M;

void res(int X[N][N], int Xj[N][N], int n)
{
  int i,j,i0,j0,d=0,f=0,tmp[N][N];
      
  for(i=0;i<N;i++) {
    for(j=0;j<N;j++) {
      if(A[i][j]!=X[i][j]) f++;
      if(X[i][j]==0) {
    i0=i;
    j0=j;
      }
      else
    d+=abs(j-P[X[i][j]])+abs(i-Q[X[i][j]]);
  
    }
  }
      
  if(f==0) {
    if(min>n) {
      min=n;
    }
    return;
  }
  if(d+n>min) return;
      
      
  if(i0>0 && i0<N) {
    memcpy(tmp,X,sizeof(int)*N*N);
    f=tmp[i0][j0];
    tmp[i0][j0]=tmp[i0-1][j0];
    tmp[i0-1][j0]=f;
    if(memcmp(tmp,Xj,sizeof(int)*N*N)!=0)
      res(tmp, X, n+1);
  }
  if(j0>0 && j0<N) {
    memcpy(tmp,X,sizeof(int)*N*N);
    f=tmp[i0][j0];
    tmp[i0][j0]=tmp[i0][j0-1];
    tmp[i0][j0-1]=f;
    if(memcmp(tmp,Xj,sizeof(int)*N*N)!=0)
      res(tmp, X, n+1);
  }
      
  if(i0>=0 && i0<N-1) {
    memcpy(tmp,X,sizeof(int)*N*N);
    f=tmp[i0][j0];
    tmp[i0][j0]=tmp[i0+1][j0];
    tmp[i0+1][j0]=f;
    if(memcmp(tmp,Xj,sizeof(int)*N*N)!=0)
      res(tmp, X, n+1);
  }
  if(j0>=0 && j0<N-1) {
    memcpy(tmp,X,sizeof(int)*N*N);
    f=tmp[i0][j0];
    tmp[i0][j0]=tmp[i0][j0+1];
    tmp[i0][j0+1]=f;
    if(memcmp(tmp,Xj,sizeof(int)*N*N)!=0)
      res(tmp, X, n+1);
  }
      
}

int main()
{
  int i,j,X[N][N];

  for(i=0; i<N; i++){
    for(j=0; j<N; j++){
      scanf("%d",&X[i][j]);
    }
  }
  res(X,X,0);

  printf("%d\n",min);
  return 0;
}