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>
  
int pz[4][4];
int tmp[4][4];
int dx[4] = {0,1,0,-1};
int dy[4] = {1,0,-1,0};
  
void empty(int *,int *);
int dfs(int,int,int,int,int);
int cal();
void swap(int *,int *);
  
int main() {
  int i,j,k,a,x,y;
    for(i = 0; i < 4; i++)
      {
        for(j = 0; j < 4; j++)
	  scanf("%d",&pz[i][j]);
      }
  
    empty(&x,&y);
    for(k = 0; k < 100; k++) {
        for(i = 0; i < 4; i++) {
            for(j = 0; j < 4; j++) tmp[i][j] = pz[i][j];
        }
  
        a = dfs(x,y,-1,0,k);
        if(a!=-1) {
            printf("%d\n",a);
            break;
        }
  
        for(i = 0 ; i < 4; i++) {
            for(j = 0 ; j < 4; j++) pz[i][j] = tmp[i][j];
        }
        a = -1;
        if(k == 99) printf("%d\n",a);
    } 
    return 0;
}
  
void empty(int *x,int *y)
{
    int p,q;
    for(p = 0;p < 4; p++)
      {
        for(q = 0; q < 4; q++)
	  {
            if(!pz[p][q])
	      {
                *x = q;
                *y = p;
                return;
	      }
	  }
      }
}

void swap(int *m,int *n)
{
    int sw;
    sw = *m;
    *m = *n;
    *n = sw;
}
  
  
int cal()
{
    int i,s,sum=0;
    for(i = 0; i < 16; i++)
      {
        s = pz[i/4][i%4];
        if(s)
	  {
            s--;
            sum += abs(i/4 - s/4) + abs(i%4 - s%4);
	  }
      }
    return sum;
}
  
  
int dfs(int x,int y,int p,int dep,int lim)
{
    int i,h,fx,fy,res;
  
    h = cal();
    if(h==0) return dep;
    if(dep+h>lim) return -1;
  
    for(i=0; i<4; i++)
      {
        fx = x+dx[i];
        fy = y+dy[i];
  
        if((~p && i == (p+2) % 4) || (!(0 <= fx && fx < 4 && 0 <= fy && fy < 4))) continue;
  
        swap(&pz[y][x],&pz[fy][fx]);
        res = dfs(fx,fy,i,dep+1,lim);
        if(~res) return res;
  
        swap(&pz[y][x],&pz[fy][fx]);
      }
  
    return -1;
}