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>
#include <stdlib.h>
#include <string.h>
#include <limits.h>


typedef struct node{
  char s[10];
  int t;
  int x;
  struct node *next;
  struct node *back;
}Node;

char *move_up(char s[], int x) {
  if(x < 3) return NULL;
  char *s_new;
  s_new = (char*)malloc(sizeof(char)*10);
  strcpy(s_new,s);
  s_new[x] = s[x-3];
  s_new[x-3] = s[x];
  return s_new;
}

char *move_left(char s[], int x) {
  if(x%3 == 0) return NULL;
  char *s_new;
  s_new = (char*)malloc(sizeof(char)*10);
  strcpy(s_new,s);
  s_new[x] = s[x-1];
  s_new[x-1] = s[x];
  return s_new;
}

char *move_right(char s[], int x) {
  if(x%3 == 2) return NULL;
  char *s_new;
  s_new = (char*)malloc(sizeof(char)*10);
  strcpy(s_new,s);
  s_new[x] = s[x+1];
  s_new[x+1] = s[x];
  return s_new;
}

char *move_down(char s[], int x) {
  if(x > 5) return NULL;
  char *s_new;
  s_new = (char*)malloc(sizeof(char)*10);
  strcpy(s_new,s);
  s_new[x] = s[x+3];
  s_new[x+3] = s[x];
  return s_new;
}

int create(Node *root, char s[], int t) {
  if(strcmp(s,"123456780") == 0) return t;
  Node *p = (Node*)malloc(sizeof(Node));
  strcpy(p->s,s);
  p->t = t;
  int i;
  for(i = 0; i < 9; i++) {
    if(s[i] == '0') {
      p->x = i;
      break;
    }
  }
  root->back->next = p;
  p->back = root->back;
  p->next = root;
  root->back = p;
  return -1;
}

int distance(char *s_new) {
  char s[] = "123456780";
  int i;
  int sum = 0;
  for(i = 0; i < 9; i++) {
    int a = 0;
    int b = 0;
    while(s[a]-'0' != i) a++;
    while(s_new[b]-'0' != i) b++;
    sum += abs(a/3-b/3) + abs(a%3-b%3);
  }
  return sum;
}

int cal(Node *root) {
  Node *p = root->next;
  char *s_right,*s_left,*s_up,*s_down;
  int right,left,up,down,min;
  int k;
  if((s_right = move_right(p->s, p->x)) != NULL) {
    right = distance(s_right);
  }else{
    right = INT_MAX;
  }
  if((s_left = move_left(p->s, p->x)) != NULL) {
    left = distance(s_left);
  }else{
    left = INT_MAX;
  }
  if ((s_up = move_up(p->s, p->x)) != NULL) {
    up = distance(s_up);
  }else{
    up = INT_MAX;
  }
  if((s_down = move_down(p->s, p->x)) != NULL) {
    down = distance(s_down);
  }else{
    down = INT_MAX;
  }

  min = right;
  if(min > left) min = left;  
  if(min > up) min = up;  
  if(min > down) min = down;

  if(right == min) {
    if((k = create(root,s_right,p->t+1)) != -1) return k;
  }
  if(left == min) {
    if((k = create(root,s_left,p->t+1)) != -1) return k;
  }
  if(up == min) {
    if((k = create(root,s_up,p->t+1)) != -1) return k;
  }
  if(down == min) {
    if((k = create(root,s_down,p->t+1)) != -1) return k;
  }

  if(s_right != NULL) free(s_right);
  if(s_left != NULL) free(s_left);
  if(s_up != NULL) free(s_up);
  if(s_down != NULL) free(s_down);
  p->next->back = root;
  root->next = p->next;
  free(p);
  return -1;
}
  

int solve(char s0[]) {
  int t;
  Node root;
  root.next = &root;
  root.back = &root;
  if((t = create(&root,s0,0)) != -1) return t;
  
  while(1) {
    if((t = cal(&root)) != -1) break;
  }
  return t;
}

int main()
{
  int i,d;
  char s[10];
  for (i = 0; i < 9; i++) {
    scanf("%d", &d);
    s[i] = d+'0';
  }
  s[9] = '\0';
  printf("%d\n",solve(s));
  
  return 0;
}