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>
 
#define S 9
 
int board[S];
int rows = 3, cols = 3, zeroIndex;
 

int blindSearch(int x, int y, int moves, int previousMove) {
  int i, foundAnswer;
 
 
  if (moves < (x + y))
    return 0;
 
  if (!moves) {
    for (i = 0; i < S - 1; i++) {
      if (board[i] != i + 1)
        return 0;
    }
 
    return 1;
  }
 
  if (x > 0 && previousMove != 1) {
    // can expand down
    board[zeroIndex] = board[zeroIndex + rows];
    zeroIndex += rows;
 
    foundAnswer = blindSearch(x - 1, y, moves - 1, 0);
    if (foundAnswer)
      return 1;
 
    board[zeroIndex] = board[zeroIndex - rows];
    zeroIndex -= rows;
  }
 
  if (y > 0 && previousMove != 3) {
    // right
    board[zeroIndex] = board[zeroIndex + 1];
    zeroIndex++;
 
    foundAnswer = blindSearch(x, y - 1, moves - 1, 2);
    if (foundAnswer)
      return 1;
 
    board[zeroIndex] = board[zeroIndex - 1];
    zeroIndex--;
  }
 
  if (y < rows - 1 && previousMove != 2) {
    // left
    board[zeroIndex] = board[zeroIndex - 1];
    zeroIndex--;
 
    foundAnswer = blindSearch(x, y + 1, moves - 1, 3);
    if (foundAnswer)
      return 1;
 
    board[zeroIndex] = board[zeroIndex + 1];
    zeroIndex++;
  }
 
  if (x < cols - 1 && previousMove != 0) {
    // up
    board[zeroIndex] = board[zeroIndex - rows];
    zeroIndex -= rows;
 
    foundAnswer = blindSearch(x + 1, y, moves - 1, 1);
    if (foundAnswer)
      return 1;
 
    board[zeroIndex] = board[zeroIndex + rows];
    zeroIndex += rows;
  }
 
  return 0;
}
 
int main() {
  int j, x, y, current;
 
  for (j = 0; j < S; j++) {
    scanf("%d", &board[j]);
    if (!board[j])
      zeroIndex = j;
  }
 
  x = cols - (zeroIndex / rows) - 1;
  y = rows - (zeroIndex % cols) - 1;
 
  for (current = 0; current < 50; current++) {
    if (blindSearch(x, y, current, -1)) {
      printf("%d\n", current);
      return 0;
    }
  }
}