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

#include <stdio.h>

#define N 9

int board[N];
int rows = 3, cols = 3, zeroIndex;

// for previousMove: 0 is down, 1 is up, 2 is left, 3 is right
int blindSearch(int x, int y, int moves, int previousMove) {
  int i, foundAnswer;

  // answer is less than manhattan distance, not possible
  if (moves < (x + y))
    return 0;

  if (!moves) {
    for (i = 0; i < N - 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];

    foundAnswer = blindSearch(x, y - 1, moves - 1, 2);
    if (foundAnswer)
      return 1;

    board[zeroIndex] = board[--zeroIndex];
  }

  if (y < rows - 1 && previousMove != 2) {
    // left
    board[zeroIndex] = board[--zeroIndex];

    foundAnswer = blindSearch(x, y + 1, moves - 1, 3);
    if (foundAnswer)
      return 1;

    board[zeroIndex] = board[++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 i, x, y, current;

  for (i = 0; i < N; i++) {
    scanf("%d", &board[i]);
    if (!board[i])
      zeroIndex = i;
  }

  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;
    }
  }
}