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: Time Limit Exceeded)

using System;
using System.Linq;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;

public class Program{
    public static int N = 3;
    public static int[] STEPS = new int[]{0, 1, 0, -1, 0};
    public static void Main(){
        //var watch = new Stopwatch();
        //watch.Start();
        string filename = "";
        //filename = @"";
        TextReader reader;
        if(filename.Count()>0) reader = new StreamReader(filename);
        else reader = Console.In;
        
        var Board = new int[N, N];
        for(int i=0; i<N; i++){
            var line = reader.ReadLine().Split().Select(int.Parse).ToArray();
            for(int j=0; j<N; j++){
                Board[i, j] = line[j];
            }
        }
        
        var Goal = new int[,]{ {1, 2, 3}, {4, 5, 6}, {7, 8, 0} };
        var Target = Board2Long(Goal);
        var queue = new Queue<State>();
        var all_list = new HashSet<long>();
        queue.Enqueue(new State{table = Board, cnt = 0});
        while(queue.Count()>0){
            var curr = queue.Dequeue();
            if(all_list.Contains(Board2Long(curr.table)))continue;
            else all_list.Add(Board2Long(curr.table));
            if(Board2Long(curr.table)==Target){
                Console.WriteLine(curr.cnt);
                break;
            }

            var Now = curr.GetPos();
            var cx = Now.X;
            var cy = Now.Y;
            for(int i=0; i<4; i++){
                var nx = cx+STEPS[i+1]; 
                var ny = cy+STEPS[i];
                if(0<=nx && nx<Board.GetLength(1) && 0<=ny && ny<Board.GetLength(0)){
                    var Nex = new Pos{Y = ny, X = nx};
                    var NexMap = curr.Swap(Nex, Now);
                    queue.Enqueue(NexMap);
                }
            }
        }
        //watch.Stop();
        //Console.WriteLine($"????????????{watch.ElapsedMilliseconds}???????§?");
    }

    public static long Board2Long(int[,] board){
        var keta = board.GetLength(0)*board.GetLength(1)-1;
        long ret = 0;
        for(int i=0; i<board.GetLength(0); i++){
            for(int j=0; j<board.GetLength(1); j++){
                ret+=board[i,j]*(int)Math.Pow(10, keta-(i*board.GetLength(0)+j));
            }
        }
        return ret;
    }
}

public struct Pos{
    public int X{set; get;}
    public int Y{set; get;}
}

public struct State{
    public int cnt{set; get;}
    public int[,] table{set; get;}
    public Pos GetPos(){
        var retPos = new Pos{X = -1, Y = -1};
        for(int i=0; i<this.table.GetLength(0); i++){
            for(int j=0; j<this.table.GetLength(1); j++){
                if(this.table[i, j]==0){
                    retPos.X = j;
                    retPos.Y = i;
                }
            }
        }
        return retPos;
    }

    public State Swap(Pos pre, Pos nex){
        var _tmp = this.table.Clone() as int[,];
        var _cnt = this.cnt;
        _tmp[nex.Y, nex.X] = this.table[pre.Y, pre.X];
        _tmp[pre.Y, pre.X] = this.table[nex.Y, nex.X];
        return new State{cnt = _cnt+=1, table = _tmp};
    }
}