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 N 3
#define NN N*N
#define BACK 0
#define FOUND 1

int dfs(int *);
int visit(int *, int);
int heuristic(int *);
void printpuzzle(int *);
void puzzlecopy(int *, int *);
int zettaichi(int);


int d; //depthlimit
int goal[NN+1];

int main()
{
  int i, j, number;
  int g; // current depth
  int puzzle[NN+1]; //添字０はつかわないため＋１
  
  puzzle[0] = 0;
  for(i = 1; i <= NN; i++) {
    scanf("%d",&puzzle[i]);
  }

  d = heuristic(puzzle);
  
  goal[0] = 0;
  goal[NN] = 0;
   for(i = 1; i < NN; i++) {
     goal[i] = i;
  }


  dfs(puzzle);

  return 0;
}

int heuristic(int *puzzle)
{
  int i, j, x, tatecost, yokocost, totalcost = 0;

  for(i = 1; i <= NN; i++) {
    if(puzzle[i] != 0) {
      tatecost = zettaichi((i-1)/3 - (puzzle[i]-1)/3);
      yokocost = zettaichi((i+2)%3 - (puzzle[i]+2)%3);
	
	totalcost += tatecost + yokocost;
    }
  }

  return totalcost;
}

void printpuzzle(int *puzzle)
{
  int i, j, number = 1;
  
  for(i = 0; i < N; i++) {
    for(j = 0; j < N; j++) {
      printf(" %d",puzzle[number]);
      number++;
    }
    printf("\n");
  }
  
}

int dfs(int *puzzle)
{
  int i;

  while(1) {
    if(visit(puzzle, 0) == FOUND) break;
    d++;
  }

  return i;
}

int visit(int *puzzle, int g)
{
  int i, blanknumber, status, found;
  int copypuzzle[NN+1];

  found = 1;
  for(i = 1; i <= NN; i++) {
    if(puzzle[i] != goal[i]) {
      found = 0;
      break;
    }
  }
  if(found == 1) {
    printf("%d\n",g);
    return FOUND;
  }
  
  if(g + heuristic(puzzle) > d) return BACK;

  //空白位置の確認
  for(i = 1; i <= NN; i++) {
    if(puzzle[i] == 0) {
      blanknumber = i;
      break;
    }
  }

  //0を下と交換
  if((blanknumber-1)/3 != 2) {
    puzzlecopy(puzzle, copypuzzle);
    copypuzzle[blanknumber] = copypuzzle[blanknumber+3];
    copypuzzle[blanknumber+3] = 0;
    if(visit(copypuzzle, g+1) == FOUND) return FOUND;
  }

  //0を右と交換
  if((blanknumber+2)%3 != 2) {
    puzzlecopy(puzzle, copypuzzle);
    copypuzzle[blanknumber] = copypuzzle[blanknumber+1];
    copypuzzle[blanknumber+1] = 0;
    if(visit(copypuzzle, g+1) == FOUND) return FOUND;
  }

  //0を左と交換
  if((blanknumber+2)%3 != 0) {
    puzzlecopy(puzzle, copypuzzle);
    copypuzzle[blanknumber] = copypuzzle[blanknumber-1];
    copypuzzle[blanknumber-1] = 0;
    if(visit(copypuzzle, g+1) == FOUND) return FOUND;
  }

  //0を上と交換
  if((blanknumber-1)/3 != 0) {
    puzzlecopy(puzzle, copypuzzle);
    copypuzzle[blanknumber] = copypuzzle[blanknumber-3];
    copypuzzle[blanknumber-3] = 0;
    if(visit(copypuzzle, g+1) == FOUND) return FOUND;
  }

  return BACK;
}


int zettaichi(int x)
{
  if(x < 0) x = -x;
  return x;
}

void puzzlecopy(int *puzzle, int *copypuzzle)
{
  int i;
  
  for(i = 1; i <= NN; i++) {
    copypuzzle[i] = puzzle[i];
  }
}