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 <math.h> 
#define N 3
  
int search(int board[N][N], int min, int limit, int r_0, int c_0);
int search(int board[N][N], int min, int limit, int r_0, int c_0){
  int md_c;
  int num;
  int res[4];
  if (min == 0){
    return 0;
  }
  if (r_0 != 0) {
    md_c = min;
    num = board[r_0-1][c_0];
    md_c -= (int)fabs((num-1)/N - (r_0-1)) + (int)fabs((num-1)%N - c_0);
    md_c += (int)fabs((num-1)/N - r_0) + (int)fabs((num-1)%N - c_0);
    if (md_c <= limit - 1) {
      board[r_0-1][c_0] = 0;
      board[r_0][c_0] = num;
      res[0] = search(board, md_c, limit-1, r_0-1, c_0);
      if (res[0] == -1) {
	board[r_0-1][c_0] = num;
	board[r_0][c_0] = 0;
      }
      else {
	res[0]++;
      }
    }
    else{
      res[0] = -1;
    }
  }
  else{
    res[0] = -1;
  }
  if (r_0 != N-1) {
    md_c = min;
    num = board[r_0+1][c_0];
    md_c -= (int)fabs((num-1)/N - (r_0+1)) + (int)fabs((num-1)%N - c_0);
    md_c += (int)fabs((num-1)/N - r_0) + (int)fabs((num-1)%N - c_0);
    if (md_c <= limit - 1) {
      board[r_0+1][c_0] = 0;
      board[r_0][c_0] =num;
      res[1] = search(board, md_c, limit-1, r_0+1, c_0);
      if (res[1] == -1) {
	board[r_0+1][c_0] = num;
	board[r_0][c_0] = 0;
      }
      else{
	res[1]++;
      }
    }
    else{
      res[1] = -1;
    }
  } 
  else{
    res[1] = -1;
  }
  if (c_0 != 0) {
    md_c = min;
    num = board[r_0][c_0-1];
    md_c -= (int)fabs((num-1)/N - r_0) + (int)fabs((num-1)%N - (c_0-1));
    md_c += (int)fabs((num-1)/N - r_0) + (int)fabs((num-1)%N - c_0);
    if (md_c <= limit - 1) {
      board[r_0][c_0-1] = 0;
      board[r_0][c_0] = num;
      res[2] = search(board, md_c, limit-1, r_0, c_0-1);
      if (res[2] == -1) {
	board[r_0][c_0-1] = num;
	board[r_0][c_0] = 0;
      }
      else{
	res[2]++;
      }
    }
    else{
      res[2] = -1;
    }
  }
  else{
    res[2] = -1;
  }
  if (c_0 != N-1) {
    md_c = min;
    num = board[r_0][c_0+1];
    md_c -= (int)fabs((num-1)/N - r_0) + (int)fabs((num-1)%N - (c_0+1));
    md_c += (int)fabs((num-1)/N - r_0) + (int)fabs((num-1)%N - c_0);
    if (md_c <= limit - 1) {
      board[r_0][c_0+1] = 0;
      board[r_0][c_0] = num;
      res[3] = search(board, md_c, limit-1, r_0, c_0+1);
      if (res[3] == -1) {
        board[r_0][c_0+1] = num;
        board[r_0][c_0] = 0;
      }
      else{
	res[3]++;
      }
    }
    else{
      res[3] = -1;
    }
  }
  else{
    res[3] = -1;
  }
  if (res[0] == -1 && res[1] == -1 && res[2] == -1 && res[3] == -1){
    return -1;
  }
  else if (res[0] != -1){
    return res[0];
  }
  else if (res[1] != -1){
    return res[1];
  }
  else if (res[2] != -1){
    return res[2];
  }
  else {
    return res[3];
    }
}
int main(int argc, char *argv[]){
  int board[N][N],md,i,j,r,c,r_0,c_0,found,res;
  for (i = 0; i < N; i++) {
    for (j = 0; j < N; j++){
      scanf("%d", &board[i][j]);
    }
  }
  md = 0;
  for (i = 0; i < N * N; i++) {
    found = 0;
    for (r = 0; r < N; r++) {
      for (c = 0; c < N; c++) {
	if (board[r][c] == i) {
	  if (i == 0) {
	    r_0 = r;
	    c_0 = c;
	  }
	  else{
	    md += (int)fabs((i-1)/N - r) + (int)fabs((i-1)%N - c);
	  }
	  found = 1;
	  break;
	}
      }
      if (found == 1){
	break;
      }
    }
  }
  
  for (i = 0; ; i += 2) {
    if ((r_0 + c_0) % 2 == 0) {
      if (md % 2 == 0){
	res = search(board, md, md+i, r_0, c_0);
      }
      else{
	res = search(board, md, md+i+1, r_0, c_0);
      }
    }
    else {
      if (md % 2 == 0){
	res = search(board, md, md+i+1, r_0, c_0);
      }
      else{
	res = search(board, md, md+i, r_0, c_0);
      }
    }
    if (res != -1) break;
  }  
  printf("%d\n", res);
  return 0;
}