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 Scala (judge verdict: Memory Limit Exceeded)

import scala.io.StdIn.{readInt,readLine}
import scala.collection.mutable.HashMap

object Main {
  def right(m:scala.collection.immutable.Map[Int,Int],i:Int):Map[Int,Int] = m.updated(i, m(i+1)).updated(i+1,0)
  def left(m:Map[Int,Int],i:Int):Map[Int,Int] = m.updated(i, m(i-1)).updated(i-1,0)
  def up(m:Map[Int,Int],i:Int):Map[Int,Int] = m.updated(i, m(i-3)).updated(i-3,0)
  def down(m:Map[Int,Int],i:Int):Map[Int,Int] = m.updated(i, m(i+3)).updated(i+3,0)
  def end(m:Map[Int,Int]) = m == Map(0->1,1->2,2->3,3->4,4->5,5->6,6->7,7->8,8->0)

  def main(args:Array[String]) = {
    val p = new HashMap[Int,Int]
    val hist= new HashMap[scala.collection.immutable.Map[Int,Int], Int]
    var found = false
    var count = 0
    var idx = 0
    var k = 0
    var l = 0
    for(i<-1 to 3) {
      readLine.split(" ").map(_.toInt).foreach{ x=>
        p += (k->x)
        if(x==0) l = k
        k+=1
      }
    }

    hist += (p.toMap->l)
    while(!found) {
      val hist2 = new HashMap[scala.collection.immutable.Map[Int,Int], Int]
      for((m,i)<-hist if !found) {
        if(i % 3 != 2) {
          val r = right(m, i)
          if(end(r)) found = true
          else if(!hist.contains(r)) hist2 += (r->(i+1))
        }
        if(!found && i % 3 != 0) {
          val r = left(m, i)
          if(end(r)) found = true
          else if(!hist.contains(r)) hist2 += (r->(i-1))
        }
        if(!found && i / 3 != 0) {
          val r = up(m, i)
          if(end(r)) found = true
          else if(!hist.contains(r)) hist2 += (r->(i-3))
        }
        if(!found && i / 3 != 2) {
          val r = down(m, i)
          if(end(r)) found = true
          else if(!hist.contains(r)) hist2 += (r->(i+3))
        }
      }
      if(!found) hist ++= hist2
      count += 1
    }
    println(count)
  }

}