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: Memory Limit Exceeded)

#include<stdio.h>
#define N 4
#define QUEUE 10000000
typedef struct Data
{
  int cost;
  int tempArr[N][N];
  int lastMove;
} data;
data queue[QUEUE];
int head=0;
int tail=0;
int ansArr[N][N]={{ 1, 2, 3, 4},
		  { 5, 6, 7, 8},
		  { 9,10,11,12},
		  {13,14,15, 0}};
int tempArr[N][N];
int curMinCost=46;
void calcMinCost(data);
int get0Row(data);
int get0Col(data);
int isCorrect(data);
void printArr(void);//debugging
void enqueue(data);
data dequeue(void);
int main(void)
{
  int i,j;//counter
  data firstData;
  for(i=0;i<N;i++)
    for(j=0;j<N;j++)
      scanf("%d",&firstData.tempArr[i][j]);
  firstData.cost=0;
  firstData.lastMove=0;
  calcMinCost(firstData);
  printf("%d\n",curMinCost);
  return 0;
}
void calcMinCost(data firstData)
{
  int row,col;
  data curData;//current data
  data nextData;
  enqueue(firstData);
  while(head!=tail)
    {
      //printArr();
      curData=dequeue();
      if(curData.cost>=curMinCost) continue;
      if(isCorrect(curData)==1)
	{
	  curMinCost=curData.cost;
	  continue;
	}
      row=get0Row(curData);
      col=get0Col(curData);
      if(row!=N-1&&curData.lastMove!=3)//slide up
	{
	  nextData=curData;
	  nextData.tempArr[row][col]=nextData.tempArr[row+1][col];
	  nextData.tempArr[row+1][col]=0;
	  nextData.cost++;
	  nextData.lastMove=1;
	  enqueue(nextData);
	}
      if(col!=N-1&&curData.lastMove!=4)//slide left
	{
	  nextData=curData;
	  nextData.tempArr[row][col]=nextData.tempArr[row][col+1];
	  nextData.tempArr[row][col+1]=0;
	  nextData.cost++;
	  nextData.lastMove=2;
	  enqueue(nextData);
	}
      if(row!=0&&curData.lastMove!=1)//slide down
	{
	  nextData=curData;
	  nextData.tempArr[row][col]=nextData.tempArr[row-1][col];
	  nextData.tempArr[row-1][col]=0;
	  nextData.cost++;
	  nextData.lastMove=3;
	  enqueue(nextData);
	}
      if(col!=0&&curData.lastMove!=2)//slide right
	{
	  nextData=curData;
	  nextData.tempArr[row][col]=nextData.tempArr[row][col-1];
	  nextData.tempArr[row][col-1]=0;
	  nextData.cost++;
	  nextData.lastMove=4;
	  enqueue(nextData);
	}
    }
}
int get0Row(data d)
{
  int i,j;//counter
  for(i=0;i<N;i++)
    for(j=0;j<N;j++)
      if(d.tempArr[i][j]==0) return i;
  return -1;
}
int get0Col(data d)
{
  int i,j;//counter
  for(i=0;i<N;i++)
    for(j=0;j<N;j++)
      if(d.tempArr[i][j]==0) return j;
  return -1;
}
int isCorrect(data d)
{
  int i,j;//counter
  for(i=0;i<N;i++)
    for(j=0;j<N;j++)
      if(ansArr[i][j]!=d.tempArr[i][j]) return 0;
  return 1;
}
void printArr(void)
{
  int i,j;//counter
  for(i=0;i<N;i++)
    {
      for(j=0;j<N;j++)
	{
	  printf("%d ",tempArr[i][j]);
	}
      printf("\n");
    }
}
void enqueue(data d)
{
  queue[tail]=d;
  tail=(tail+1)%QUEUE;
}
data dequeue(void)
{
  int retIndex=head;
  head=(head+1)%QUEUE;
  return queue[retIndex];
}