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];
    //printf("A\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;
}