Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

8 Puzzle

The goal of the 8 puzzle problem is to complete pieces on $3 \times 3$ 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 8 as shown below.

1 3 0
4 2 5
7 8 6

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 0

Write a program which reads an initial state of the puzzle and prints the fewest steps to solve the puzzle.

Input

The $3 \times 3$ integers denoting the pieces or space are given.

Output

Print the fewest steps in a line.

Constraints

There is a solution.

Sample Input

1 3 0
4 2 5
7 8 6

Sample Output

4

Solution in C (judge verdict: Accepted)

#include<stdio.h>
#include<string.h>

#define N 3
#define LIM 32
#define HN 362897

struct dep{
  int depth,key;
};

int ans[N][N]={
  {1,2,3},
  {4,5,6},
  {7,8,0}
};

int min = LIM;
struct dep h[HN];

int hash1(int k)
{
  return k % HN;
}
int hash2(int k)
{
  return 1 + k%(HN-1);
}
int hash(int k, int i)
{
  return (hash1(k) + i*hash2(k))%HN;
}


void dfs(int p[N][N], int n)
{
  int i,j,i0,j0,a=0,b=1;
  int f=0;
  int tmp[N][N];
  for(i=0;i<N;i++)
  {
    for(j=0;j<N;j++)
    {
      if(ans[i][j]!=p[i][j])f++;
      if(p[i][j]==0)
      {
        i0=i;
        j0=j;
      }
      a+=p[i][j]*b;
      b*=10;
    }
  }

  if(f==0)
  {
    if(min>=n)
    {
      min=n;
    }
    return;
  }
  if(n>min) return;
  i=0;
  while(1)
  {
    b=hash(a, i);
    if(h[b].key == 0)
    {
      h[b].key=a;
      h[b].depth=n;
      break;
    }
    else if(h[b].key == a)
    {
      if(h[b].depth>n)
      {
        h[b].depth=n;
        break;
      }
      else return;
    }
    i++;
  }

  if(i0>0 && i0<N)
  {
    memcpy(tmp,p,sizeof(int)*N*N);
    f=tmp[i0][j0];
    tmp[i0][j0]=tmp[i0-1][j0];
    tmp[i0-1][j0]=f;
    dfs(tmp, n+1);
  }
  if(j0>0 && j0<N)
  {
    memcpy(tmp,p,sizeof(int)*N*N);
    f=tmp[i0][j0];
    tmp[i0][j0]=tmp[i0][j0-1];
    tmp[i0][j0-1]=f;
    dfs(tmp, n+1);
  }

  if(i0>=0 && i0<N-1)
  {
    memcpy(tmp,p,sizeof(int)*N*N);
    f=tmp[i0][j0];
    tmp[i0][j0]=tmp[i0+1][j0];
    tmp[i0+1][j0]=f;
    dfs(tmp, n+1);
  }
  if(j0>=0 && j0<N-1)
  {
    memcpy(tmp,p,sizeof(int)*N*N);
    f=tmp[i0][j0];
    tmp[i0][j0]=tmp[i0][j0+1];
    tmp[i0][j0+1]=f;
    dfs(tmp, n+1);
  }

}

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

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

  printf("%d\n",min);

  return 0;
}