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 C# (judge verdict: Runtime Error)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class State
    {
        internal int[,] map;
        internal string moveLog;
        internal char preMove;
    }

    class NPuzzle
    {
        readonly int n, h, w;

        public NPuzzle(int h, int w)
        {
            n = h * w;
            this.h = h;
            this.w = w;
        }

        public string Solve(State s)
        {
            Queue<State> que = new Queue<State>();
            que.Enqueue(s);

            while (que.Count > 0)
            {
                State cur = que.Dequeue();

                if (IsGoal(cur)) return cur.moveLog;

                KeyValuePair<int, int> spacePos = FindSpace(cur);
                int x = spacePos.Value;
                int y = spacePos.Key;

                if (x != 0 && cur.preMove != 'l')
                {
                    State saved = new State();
                    saved.map = (int[,])cur.map.Clone();
                    saved.map[y, x - 1] = 0;
                    saved.map[y, x] = cur.map[y, x - 1];
                    saved.moveLog = cur.moveLog + "r";
                    saved.preMove = 'r';
                    que.Enqueue(saved);
                }

                if (x != w - 1 && cur.preMove != 'r')
                {
                    State saved = new State();
                    saved.map = (int[,])cur.map.Clone();
                    saved.map[y, x + 1] = 0;
                    saved.map[y, x] = cur.map[y, x + 1];
                    saved.moveLog = cur.moveLog + "l";
                    saved.preMove = 'l';
                    que.Enqueue(saved);
                }

                if (y != 0 && cur.preMove != 'u')
                {
                    State saved = new State();
                    saved.map = (int[,])cur.map.Clone();
                    saved.map[y - 1, x] = 0;
                    saved.map[y, x] = cur.map[y - 1, x];
                    saved.moveLog = cur.moveLog + "d";
                    saved.preMove = 'd';
                    que.Enqueue(saved);
                }

                if (y != h - 1 && cur.preMove != 'd')
                {
                    State saved = new State();
                    saved.map = (int[,])cur.map.Clone();
                    saved.map[y + 1, x] = 0;
                    saved.map[y, x] = cur.map[y + 1, x];
                    saved.moveLog = cur.moveLog + "u";
                    saved.preMove = 'u';
                    que.Enqueue(saved);
                }
            }
            return null;
        }

        private KeyValuePair<int, int> FindSpace(State s)
        {
            for (int i = 0; i < h; i++)
            {
                for (int j = 0; j < w; j++)
                {
                    if (s.map[i, j] == 0) return new KeyValuePair<int, int>(i, j);
                }
            }
            return new KeyValuePair<int, int>(-1, -1);
        }

        private bool IsGoal(State s)
        {
            int mustNumber = 0;

            for (int i = 0; i < h; i++)
            {
                for (int j = 0; j < w; j++)
                {
                    ++mustNumber;

                    if (mustNumber != n && s.map[i, j] != mustNumber) return false;
                }
            }
            return true;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int h = 3, w = 3;

            NPuzzle NP = new NPuzzle(h, w);
            State s = new State();
            s.map = new int[h, w];

            for (int i = 0; i < h; i++)
            {
                int[] input = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse);

                for (int j = 0; j < w; j++)
                {
                    s.map[i, j] = input[j];
                }
            }

            string ans = NP.Solve(s);

            Console.WriteLine(ans.Length);
        }
    }
}