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: Accepted)

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

namespace ALDS1_13_B
{
    class Program
    {
        const int N = 3;
        const int N2 = 9;
        static int[] dx = { -1, 0, 1, 0 };
        static int[] dy = { 0, -1, 0, 1 };
        static char[] dir = { 'u', 'l', 'd', 'r' };
        static int cnt;

        class Puzzle
        {
            internal int[] f;
            internal int space;
            internal string path;
            
            public Puzzle()
            {
                f = new int[N2];
                space = -1;
                path = "";
            } 
        }
        static void Main(string[] args)
        {
            var P = new Puzzle();
            for (int i = 0; i < N; i++)
            {
                var k = scan;
                for (int j = 0; j < N; j++)
                {
                    P.f[cnt++] = k[j];
                    if (k[j] == 0)
                    {
                        P.f[cnt - 1] = N2;
                        P.space = cnt - 1;
                    }
                }
            }
            bfs(P);
        }

        static void bfs(Puzzle s)
        {
            var Q = new Queue<Puzzle>();

            string st = "";
            for (int i = 0; i < 9; i++)
            {
                st += s.f[i].ToString();
            }
            var V = new HashSet<string>();

            var u = new Puzzle();
            var v = new Puzzle();

            Q.Enqueue(s);
            V.Add(st);
       

            while (Q.Any())
            {
                u = Q.Dequeue();

                
                if(isTarget(u))
                {
                    Console.WriteLine(u.path.Length);
                    return;
                }

                int sx = u.space / N;
                int sy = u.space % N;

                for (int r = 0; r < 4; r++)
                {
                    int tx = sx + dx[r];
                    int ty = sy + dy[r];
                    if (tx < 0 || ty < 0 || tx >= N || ty >= N) continue;

                    var us = u.space;
                    var vs = tx * N + ty;

                    v = new Puzzle();
                    for (int i = 0; i < 9; i++)
                    {
                        v.f[i] = u.f[i];
                    }
                    int tt = v.f[us];
                    v.f[us] = v.f[vs];
                    v.f[vs] = tt;


                    v.space = vs;
                    v.path = u.path;
  

                    st = "";
                    for (int i = 0; i < 9; i++)
                    {
                        st += v.f[i].ToString();
                    }

                    if (!V.Contains(st))
                    {
                        V.Add(st);
                        v.path += dir[r];
                        Q.Enqueue(v);
                     }
                }
            }

            Console.WriteLine("unsolvable");
        }


        static bool isTarget(Puzzle p)
        {
            for (int i = 0; i < N2; i++)
            {
                if (p.f[i] != (i + 1)) return false;
            }
            return true;
        }
        static int[] scan { get { return Array.ConvertAll(Console.ReadLine().Split(), int.Parse); } }
    }
}