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.Linq;
using System.Collections.Generic;
using static System.Console;
using System.Text;
using System.IO;

namespace AOJ
{
    class Program
    {
        static public long[] Sarray() { return ReadLine().Trim().Split().Select(long.Parse).ToArray(); }
        static public List<long> Slist() { return ReadLine().Split().Select(long.Parse).ToList(); }

        static void Main(string[] args)
        {
            var n = 3;
            var n2 = n * n;
            var masu = new int[n, n];
            for (var i = 0; i < n; ++i)
            {
                var num = Sarray();
                for (var j = 0; j < n; ++j)
                    masu[i, j ] = (int)num[j];
            }
            var e = new EPuzzle(masu);
            WriteLine(e.bfs().Length);
        }
        class EPuzzle
        {
            public class Puzzle :IEquatable<Puzzle>
            {
                public int space;
                public string path;
                public int[] f;
                public Puzzle(int N2, int space, int MD)
                {
                    this.space = space;
                    f = new int[N2];
                    path = string.Empty;
                }
                public Puzzle(Puzzle p)
                {
                    space = p.space;
                    path = p.path;
                    f = new int[p.f.Length];
                    Array.Copy(p.f, f, p.f.Length);
                }
                public bool Equals(Puzzle other) => this.f.SequenceEqual(other.f);
                public override int GetHashCode() => f.Aggregate(0, (acc, i) => unchecked(acc * 457 + i * 389));
            }
            readonly int[] dx = new int[] { 0, -1, 0, 1 };//Height
            readonly int[] dy = new int[] { 1, 0, -1, 0 };//Width
            readonly string dir = "ruld";
            readonly int N;
            readonly int N2;
            Puzzle p;
            public EPuzzle(int[,] inp)
            {
                N = inp.GetLength(0);
                N2 = N * N;
                p = new Puzzle(N2, 0, 0);
                for(var i=0;i<N;++i)
                    for(var j=0;j<N;++j)
                    {
                        p.f[i * N + j] = inp[i, j];
                        if (p.f[i * N + j] == 0)
                        {
                            p.space = i * N + j;
                            p.f[i * N + j] = N2;
                        }
                    }
            }
            bool isTarget(Puzzle p)
            {
                for (var i = 0; i < N2; ++i)
                    if (p.f[i] != i + 1) return false;
                return true;
            }
            public string bfs()
            {
                var Q = new Queue<Puzzle>();
                var V = new HashSet<Puzzle>();

                Q.Enqueue(p);
                V.Add(p);

                while(Q.Any())
                {
                    var u = Q.Dequeue();
                    if (isTarget(u)) return u.path;
                    var sx = u.space / N;
                    var sy = u.space % N;
                    for (var r = 0; r < 4; ++r)
                    {
                        var tx = sx + dx[r];
                        var ty = sy + dy[r];
                        if (tx < 0 || ty < 0 || N <= tx || N <= ty) continue;
                        var v = new Puzzle(u);

                        v.f[u.space] = v.f[tx * N + ty];
                        v.f[tx * N + ty] = N2;
                        v.space = tx * N + ty;

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