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

class Puzzle
  attr_accessor :s, :cou, :direction
  def initialize(s, direction, cou=-1)
    @s = s
    @cou = cou
    @direction = direction
  end

  def calc
    nums = @s.dup
    @s.each_with_index do |x, i_x|
      @s[i_x..-1].each_with_index do |y, i_y|
        nums[i_x + i_y] -= 1 if y > x
      end
    end
    number = 0
    nums.each_with_index do |x, i_x|
      factorial = (nums.size - 1 - i_x).downto(1).inject(:*)
      number += factorial * x if factorial != nil
    end
    return number
  end

  def zero
    return @s.index(0)
  end
end

class Dic
  attr_reader :visit, :cou
  def initialize(num)
    @visit = Array.new(num, 1)
    @cou = Array.new(num, 0)
  end
  def visited?(id, direction)
    return @visit[id] != 1 && @visit[id] % direction == 0
  end
  def visit(puzzle)
    id = puzzle.calc
    direction = puzzle.direction
    cou = puzzle.cou
    @visit[id] *= direction
    @cou[id] += cou
  end

  def get(puzzle)
    return cou[puzzle.calc]
  end
end

move = [[1, 3],
        [0, 2, 4],
        [1, 5],
        [0, 4, 6],
        [1, 3, 5, 7],
        [2, 4, 8],
        [3, 7],
        [4, 6, 8],
        [5, 7]]

col = [1, 2, 3, 4, 5, 6, 7, 8, 0]

f = 2
b = 3

# main
init_s = []
3.times do
  init_s.concat(gets.chomp.split.map(&:to_i))
end

queue = []
init = Puzzle.new(init_s, f, 0)
goal = Puzzle.new(col, b, 0)
queue << init
queue << goal

dict = Dic.new(9.downto(1).inject(:*))
dict.visit(init)
dict.visit(goal)

while queue.size > 0 do
  puzzle = queue.shift
  id = puzzle.calc
  if dict.visited?(id, f) && dict.visited?(id, b) then
    puts dict.cou[id]
    break
  end

  zero = puzzle.zero
  swap = move[zero]

  swap.each{|swap_pos|
    new = Puzzle.new(puzzle.s.dup,puzzle.direction,puzzle.cou+1)
    new.s[zero], new.s[swap_pos] = new.s[swap_pos], new.s[zero]
    next if dict.visited?(new.calc, new.direction)
    queue << new
    dict.visit(new)
  }
end