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<string.h>
#include<stdlib.h>
#define N 4
#define T 1
#define F 0

int dx[4] = {0,-1,0,1}, dy[4] = {1,0,-1,0}, limit, t[N][N];

void swap(int *x,int *y)
{
  int tmp = *x;

  *x = *y;
  *y = tmp;

  return;
}

int Heuristic()
{
  int i, j, sum = 0, x;

  for(i = 0; i < N; i++)
    for(j = 0; j < N; j++){
      if(t[i][j] == 0)
	continue;
      x = t[i][j] -1;
      sum += abs(x/4-i) + abs(x%4-j);
    }

  return sum;
}

int dfs(int depth, int prev, int py, int px)
{
  int i, h, tx, ty;
  h = Heuristic();
  if (h == 0)
    return T;
  if (depth+h > limit)
    return F;
  for (i = 0; i < 4; i++){
    if(abs(i-prev) == 2)
      continue;
    tx=px+dx[i];
    ty=py+dy[i];
    if(tx < 0 || ty < 0 || tx >= N || ty >= N)
      continue;
    swap(&t[ty][tx],&t[py][px]);
    if(dfs(depth+1,i,ty,tx))
      return T;
    swap(&t[ty][tx],&t[py][px]);
  }
  return F;
}

void issolved(int py,int px)
{
  for(limit = 0;; limit++)
    if(dfs(0,99,py,px)){
      printf("%d\n",limit);
      return;
    }
}

int main()
{
  int i,j,px,py;

  for(i = 0; i < N; i++)
    for(j = 0; j < N; j++){
      scanf("%d",&t[i][j]);
      if(t[i][j] == 0){
        py = i;
        px = j;
      }
    }
  issolved(py,px);
  
  return 0;
}