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 JavaScript (judge verdict: Accepted)

class Node {
  constructor(board = [], zeroIndex = null, parent = null) {
    this.board = board;
    this.zeroIndex = zeroIndex || this.getZeroIndex();
    this.parent = parent;
  }

  getZeroIndex() {return this.board.indexOf(0);}

  get depth() {
    let node = this, depth = 0;
    while ((node = node.parent)) depth++;
    return depth;
  }
}

class EightPazzle {
  init() {
    EightPazzle.inited = true;
    EightPazzle.correct_board = [1, 2, 3, 4, 5, 6, 7, 8, 0];
    EightPazzle.adjLists = [
      [1, 3], [0, 2, 4], [1, 5],
      [0, 4, 6], [1, 3, 5, 7], [2, 4, 8],
      [3, 7], [4, 6, 8], [5, 7]
    ];
  }

  constructor(begin_board) {
    EightPazzle.inited || this.init();
    this.cache = {begin_board: true};
    this.queue = [new Node(begin_board)];
  }

  solve() {
    const cb = EightPazzle.correct_board.toString();
    const isCorrect = (n) => n.board.toString() === cb;
    if (isCorrect(this.queue[0])) return this.queue[0];

    let node, newNode, board, zeroIdx, flg;
    while ((node = this.queue.shift()) !== undefined) {
      zeroIdx = node.zeroIndex;
      
      flg = EightPazzle.adjLists[zeroIdx].some(next => {
        board = [].concat(node.board);
        board[zeroIdx] = [board[next], board[next] = board[zeroIdx]][0];
        newNode = new Node(board, next, node);
        if (!this.cache[board]) {
          if (isCorrect(newNode)) return true;
          this.cache[board] = true;
          this.queue.push(newNode);
        }
        return false;
      });
      if (flg) return newNode;
    }
  }
}

(function main() {
  const board = require('fs').readFileSync('/dev/stdin', 'utf8').trim().split(/[ \n]/).map(Number);
  const E = new EightPazzle(board);
  console.log(E.solve().depth);
})();