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++14 (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

set<int> dp;

class eightPuzzle {
 public:
    int table[3][3];
    int x, y;
};

int UP = 0, LEFT = 1, RIGHT = 2, DOWN = 3;
eightPuzzle move(eightPuzzle p, int dir) {
    eightPuzzle newp;
    for (int i = 0; i < 3; i++) {
        memcpy(newp.table[i], p.table[i], sizeof(p.table[i]));
    }
    newp.x = p.x;
    newp.y = p.y;

    if (dir == UP && newp.y + 1 < 3) {
        swap(newp.table[newp.y][newp.x], newp.table[newp.y + 1][newp.x]);
        newp.y++;
    } else if (dir == LEFT && newp.x + 1 < 3) {
        swap(newp.table[newp.y][newp.x], newp.table[newp.y][newp.x + 1]);
        newp.x++;
    } else if (dir == RIGHT && newp.x - 1 >= 0) {
        swap(newp.table[newp.y][newp.x], newp.table[newp.y][newp.x - 1]);
        newp.x--;
    } else if (dir == DOWN && newp.y - 1 >= 0) {
        swap(newp.table[newp.y][newp.x], newp.table[newp.y - 1][newp.x]);
        newp.y--;
    }
    return newp;
}

// 8パズルをハッシュ化する関数
int eightHash(eightPuzzle p) {
    int ret = 0;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            ret += p.table[i][j] * pow(10, 3 * i + j);
        }
    }
    return ret;
}

// ゴールに到達したかを判定する
bool goal(eightPuzzle p) {
    bool flag = true;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (p.table[i][j] != (3 * i + j + 1) % 9) flag = false;
            if (!flag) break;
        }
        if (!flag) break;
    }
    return flag;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    eightPuzzle p;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cin >> p.table[i][j];
            if (p.table[i][j] == 0) {
                p.x = j;
                p.y = i;
            }
        }
    }
    if (goal(p)) {
        cout << 0 << endl;
        return 0;
    }
    int ehash = eightHash(p);
    dp.insert(ehash);
    queue<pair<eightPuzzle, int>> q;
    q.push(make_pair(p, 0));
    while (true) {
        int cnt;
        eightPuzzle ep;
        tie(ep, cnt) = q.front();
        q.pop();
        for (int i = 0; i < 4; i++) {
            eightPuzzle np = move(ep, i);
            if (goal(np)) {
                cout << cnt + 1 << endl;
                return 0;
            }
            int h = eightHash(np);
            if (dp.find(h) == dp.end()) {
                q.push(make_pair(np, cnt + 1));
                dp.insert(h);
            }
        }
    }

    return 0;
}