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
import scala.collection.mutable.ArrayBuffer

object Main {

  def move(m:Int, d1:Int, d2:Int) = {
    val x = m/d2 % 10
    m + (9+x) * (d2-d1)
  }
  def end(m:Int) = m == 123456789

  def main(args:Array[String]) = {
    val hist = new ArrayBuffer[Int]
    val phist = new ArrayBuffer[Int]
    val map = new HashMap[Int,Int]
    var pointer = 0
    var found = false
    var count = 0

    val s = { for(i<-1 to 3) yield readLine.split(" ").reduce(_+_) }.reduce(_+_)
    val idx = 8-s.indexWhere(_=='0')
    phist += idx

    val n = s.map{ c => if(c=='0') '9' else c }.toInt
    hist += n
    map += (n->1)

    if(end(n)) found = true
    while(!found) {
      val len = hist.length
      for(i<-pointer until len if !found) {
        val pos = phist(i)
        val data = hist(i)
        val p = Math.pow(10,pos).toInt
        if((8-pos)%3 != 2) {
          val r = move(data, p, p/10)
          if(end(r)) found = true
          else if(!map.contains(r)) {
            hist += r
            map += (r->1)
            phist += pos-1
          }
        }
        if(!found && (8-pos) % 3 != 0) {
          val r = move(data, p, p*10)
          if(end(r)) found = true
          else if(!map.contains(r)) {
            hist += r
            map += (r->1)
            phist += pos+1
          }
        }
        if(!found && (8-pos) / 3 != 0) {
          val r = move(data, p, p*1000)
          if(end(r)) found = true
          else if(!map.contains(r)) {
            hist += r
            map += (r->1)
            phist += pos+3
          }
        }
        if(!found && (8-pos) / 3 != 2) {
          val r = move(data, p, p/1000)
          if(end(r)) found = true
          else if(!map.contains(r)) {
            hist += r
            map += (r->1)
            phist += pos-3
          }
        }
      }
      pointer = (len-pointer)
      count += 1
    }
    println(count)
  }

}