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: Time Limit Exceeded)


class Puzzle
  attr_accessor :mat, :cost
  def initialize(mat)
    @mat = mat
    @cost = 9 - distance
  end
  def >(other)
    return self.cost < other.cost ? true : false
  end
  def <(other)
    return self.cost > other.cost ? true : false
  end
  def distance
    goal = [1,2,3,4,5,6,7,8,0]
    d = 0
    9.times{|i|
      d += 1 if @mat[i] == goal[i]
    }
    return d
  end
end


class Heep
  def initialize
    @node = []
  end
  def insert(num)
    i = @node.size
    @node[i] = num
    p = (i+1)/2-1
    while i > 0 && @node[p] < @node[i]
      @node[i], @node[p] = @node[p], @node[i]
      i = p
      p = (i+1)/2-1
    end
  end
  def extract
    ret = @node[0]
    if @node.size > 1
      @node[0] = @node.pop()
      maxHeapify(0)
    else
      @node = []
    end
    return ret
  end
  def maxHeapify(i)
    h = @node.size
    largest = i
    l = 2 * i + 1
    largest = l if l < h && @node[l] > @node[largest]
    r = 2 * i + 2
    largest = r if r < h && @node[r] > @node[largest]
    if largest != i then
      @node[i], @node[largest] = @node[largest], @node[i]
      maxHeapify(largest)
    end
  end
  def size
    return @node.size
  end
  def contain(node)
    if @node.index(node) == nil
      return false
    else
      return true
    end
  end
end

mat = []
3.times{|i|
  mat[3*i], mat[3*i+1], mat[3*i+2] = gets.split.map(&:to_i)
}

ini = Puzzle.new(mat)
q = Heep.new
q.insert(ini)

steps = 0
done = {}
loop do
  newq = Heep.new
  loop do
    break if q.size == 0
    theMat = q.extract
    p theMat
    if theMat.cost == 0 then
      puts steps
    end
    done[theMat.mat.join(" ")] = true
    idx = theMat.mat.index(0)
    #Down
    unless idx < 3 then
      newMat = theMat.mat.clone
      newMat[idx], newMat[idx-3] = newMat[idx-3], newMat[idx]
      newq.insert(Puzzle.new(newMat)) unless done[newMat.join(" ")]
    end
    #Up
    unless idx > 5 then
      newMat = theMat.mat.clone
      newMat[idx], newMat[idx+3] = newMat[idx+3], newMat[idx]
      newq.insert(Puzzle.new(newMat)) unless done[newMat.join(" ")]
    end
    #Left
    unless idx % 3 == 0 then
      newMat = theMat.mat.clone
      newMat[idx], newMat[idx-1] = newMat[idx-1], newMat[idx]
      newq.insert(Puzzle.new(newMat)) unless done[newMat.join(" ")]
    end
    #Right
    unless idx % 3 == 2 then
      newMat = theMat.mat.clone
      newMat[idx], newMat[idx+1] = newMat[idx+1], newMat[idx]
      newq.insert(Puzzle.new(newMat)) unless done[newMat.join(" ")]
    end
  end
  q = newq
  steps += 1
end