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 <stdlib.h>
#include <string.h>
#define true 1
#define false 0
#define LEN 500001
#define N 3
#define N2 9

typedef struct puzzle {
	int f[N2];
	int space;
	int path;
} Puzzle;

void enqueue(Puzzle);
Puzzle dequeue();

Puzzle Q[LEN];
int head = 0, tail = 0;
int V[LEN];
static const int dx[4] = {-1, 0, 1, 0};
static const int dy[4] = {0, -1, 0, 1};

int hash(Puzzle p) {
	int i, j;
	int key, count;
	int sum = 0;

	for ( i = 0, key = 1; i < N2; key *= ++i) {
		for ( j = 0, count = 0; j < i; j++) {
			if ( p.f[j] < p.f[i] ) count++;
		}
		sum += count * key;
	}
	return sum;
}

int isTarget(Puzzle p) {
	int i;
	for ( i = 0; i < N2; i++)
		if ( p.f[i] != ( i + 1 ) ) return false;
	return true;
}

int bfs(Puzzle s) {
	Puzzle u, v;
	int r;
	s.path = 0;
	enqueue(s);
	V[hash(s)] = true;

	while ( head != tail ){
		u = Q[head];
		dequeue();
		if ( isTarget(u) == true ) return u.path;
		int sx = u.space / N;
		int sy = u.space % N;
		for ( r = 0; r < 4; r++) {
			int tx = sx + dx[r];
			int ty = sy + dy[r];
			if ( tx < 0 || ty < 0 || tx >= N || ty >= N ) continue;
			v = u;
			int temp = v.f[u.space];
			v.f[u.space] = v.f[tx * N + ty];
			v.f[tx * N + ty] = temp;
			v.space = tx * N + ty;
			if ( V[hash(v)] != true ) {
				V[hash(v)] = true;
				v.path++;
				enqueue(v);
			}
		}
	}

	return -1;
}

int main() {
	Puzzle in;
	int i;

	for ( i = 0; i < N2; i++) {
		scanf("%d",&in.f[i]);
		if (in.f[i] == 0) {
			in.f[i] = N2;
			in.space = i;
		}
	}

	int ans = bfs(in);
	printf("%d\n",ans);

	return 0;
}

void enqueue(Puzzle x) {
	Q[tail] = x;
	tail = (tail + 1) % LEN;
}

Puzzle dequeue() {
	Puzzle x = Q[head];
	head = (head + 1) % LEN; 
	return x;
}