#define C4DROID 0
//#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <cstdlib>
#include <time.h>
#if !C4DROID
#include <windows.h>
#endif
//using namespace std;
int correct;
int fact[]= {1,1,2,6,24,120,720,5040,40320};
void swp(char &x,char &y) {
char t=x;
x=y;
y=t;
}
char conv(char a) {
if(a<4) return a;
if(a=='w') return 0;
if(a=='s') return 1;
if(a=='a') return 2;
if(a=='d') return 3;
return -1;
}
class field {
public:
char *f;
int zr;
field () {
f=new char[9];
for(int i=0; i<8; ++i) f[i]=i+1;
f[zr=8]=0;
}
void mix(int hehe) {
while(hehe--) {
move(rand()&3);
}
}
field (char* F,int Zr) {
f=F;
zr=Zr;
}
char& at(int x,int y) {
return f[x+y*3];
}
void out() {
#if C4DROID
clrscr();
#else
SetConsoleCursorPosition(GetStdHandle(-11),(COORD) {
0,0
});
#endif
printf("%d %d %d\n\n%d %d %d\n\n%d %d %d\n"
,f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8]);
}
bool up() {
if(zr<3) return false;
swp(f[zr],f[zr-3]);
zr-=3;
return true;
}
bool down() {
if(zr>5) return false;
swp(f[zr],f[zr+3]);
zr+=3;
return true;
}
bool left() {
if(zr%3==0) return false;
swp(f[zr],f[zr-1]);
zr--;
return true;
}
bool right() {
if(zr%3==2) return false;
swp(f[zr],f[zr+1]);
zr++;
return true;
}
bool move(char a) {
switch(conv(a)) {
case 0:
return up();
case 1:
return down();
case 2:
return left();
case 3:
return right();
default:
return 0;
}
return 0;
}
bool good() {
return f[0]==1&&f[1]==2&&f[2]==3&&f[3]==4&&f[4]==5&&
f[5]==6&&f[6]==7&&f[7]==8;
}
field& operator =(const field &x) {
for(int i=0; i<9; ++i) f[i]=x.f[i];
zr=x.zr;
return *this;
}
};
class solution {
public:
field s;
char data[362880];/*181440 slots is ok,without1,2,5,6,9,10*/
void change(const char *a,char v) {
int r=0,i=9,j=0,c;
while(j<8) {
c=0;
for(i=j; i<9; ++i) if(a[j]>a[i]) ++c;
r=(r+c)*(8-j);
++j;
}
data[r]=v;
}
char& todata(const char* a) {
int r=0,i=9,j=0,c;
while(j<8) {
c=0;
for(i=j; i<9; ++i) if(a[j]>a[i]) ++c;
r=(r+c)*(8-j);
++j;
}
return data[r];
}
char& todata(field a) {
return todata(a.f);
}
void init() {
field *a=new field[24047],*b=new field[24047],*t;
for(int i=0; i<362880; ++i) data[i]=127;
int asize=1,bsize=0,count=0,msz=1;
field d;
a[0]=d;
change(d.f,0);
getche();
while(asize) {
count++;
bsize=0;
for(int i=0; i<asize; ++i) {
if((d=a[i]).up()&&todata(d)>count) {
b[bsize++]=d;
change(d.f,count);
}
if((d=a[i]).down()&&todata(d)>count) {
b[bsize++]=d;
change(d.f,count);
}
if((d=a[i]).left()&&todata(d)>count) {
b[bsize++]=d;
change(d.f,count);
}
if((d=a[i]).right()&&todata(d)>count) {
b[bsize++]=d;
change(d.f,count);
}
}
t=a;
a=b;
b=t;
asize=bsize;
msz+=bsize;
}
//a[0].out();
for(int i=0;i<100;++i) printf("%d %d\n",i,data[i]);
getche();
}
void get(field o) {
for(int i=0; i<9; ++i) s.f[i]=o.f[i];
s.zr=o.zr;
}
void solve() {
int count=todata(s);
field d;
while(count>0) {
printf("%d",count);
if(getche()=='q') return;
if((d=s).up()&&todata(d)<count) {
s=d;
s.out();
count--;
} else if((d=s).down()&&todata(d)<count) {
s=d;
s.out();
count--;
} else if((d=s).left()&&todata(d)<count) {
s=d;
s.out();
count--;
} else if((d=s).right()&&todata(d)<count) {
s=d;
s.out();
count--;
}
}
}
};
solution sol;
int main() {
srand(time(NULL));
sol.init();
field a;
correct=sol.todata(a.f);
a.out();
char op;
while(op=getche()) {
if(op=='p') {
sol.get(a);
sol.solve();
a=sol.s;
}
if(op=='m') a.mix(666);
a.move(op);
a.out();
}
}