#include <stdio.h>
#include <string.h>
#include <time.h>

char Cube[5][5][5][5],C2[5][5][5][5];

void Init(){
	for(int i=1;i<=3;i++){
		for(int j=1;j<=3;j++){
			for(int k=1;k<=3;k++){
				Cube[i][j][k][0]='1';
				Cube[i][j][k][4]='8';
				Cube[i][j][0][k]='2';
				Cube[i][j][4][k]='7';
				Cube[i][0][j][k]='3';
				Cube[i][4][j][k]='6';
				Cube[0][i][j][k]='4';
				Cube[4][i][j][k]='5';
			}
		}
	}
}
int M[12][3]={{0,2,3},{0,3,1},{0,2,1},{1,2,3},{1,0,3},{1,0,2},{2,3,0},{2,3,1},{2,1,0},{3,0,2},{3,1,0},{3,2,1}};
void Rotate(int dir,int mask,int n){
	int face=M[dir][0],v1=M[dir][1],v2=M[dir][2];
	mask=(mask&1)+mask*2+(mask&4)*4;
		for(int a=0;a<5;a++){
			for(int b=0;b<5;b++){
				for(int c=0;c<5;c++){
					for(int d=0;d<5;d++){
						int S[4]={a,b,c,d};
						char vv=Cube[a][b][c][d];
						if((1<<S[face])&mask){
							for(int i=0;i<n;i++){
								int m=S[v1]; S[v1]=4-S[v2]; S[v2]=m;
							}
						}
						C2[S[0]][S[1]][S[2]][S[3]]=vv;
					}
				}
			}
		}
		memcpy(Cube,C2,625);
}
unsigned long seed=0x1234567l;
int irand(int n){
	seed=seed*0x1010005+1;
	return (int)(((seed>>16)*n)>>16);
}
void Scramble(){
	for(int n=0;n<1000;n++){
		Rotate(irand(12),irand(6)+1,irand(3)+1);
	}
}
char scr[19][24];
void Show(){
	int i,j,k;
	for(i=0;i<19*24;i++) scr[0][i]=' ';
		for(i=0;i<3;i++){
			for(j=0;j<3;j++){
				for(k=0;k<3;k++){
					scr[i*3+j+1][k*4+j]=Cube[i+1][1+k][4][1+j];
					scr[i*3-j+12][k*4+j]=Cube[4][1+k][3-i][1+j];
					scr[i*3-j+12][k*4-j+14]=Cube[3-k][4][3-i][1+j];
					scr[i*3-j+2][k*4+j+13]=Cube[3-j][1+k][3-i][4];
				}
			}
		}
		printf("-------------------------------------------------\n");
		for(i=0;i<19;i++){
			for(j=0;j<24;j++) printf("%c ",scr[i][j]);
			printf("\n");
		}
		printf("-------------------------------------------------\n");
}
void Save(){
	FILE *f=fopen("r4d.log","wb");
	fwrite(Cube,1,625,f);
	fclose(f);
}
void Load(){
	FILE *f=fopen("r4d.log","rb");
	if(f!=0){
		fread(Cube,1,625,f);
		fclose(f);
	}
}
void Process(char *line){
	for(char *c=line;*c;c++) if(*c>='a' && *c<='z') *c-=0x20;
	int mask=4;
	for(;*line!=0;line++){
		switch(*line){
			case 'L': Load(); break;
			case 'S': Save(); break;
			case 'P': Scramble(); break;
			case 'R': mask=1; break;
			case 'M': mask=2; break;
			case 'O': mask=7; break;
			case 'A':
			case 'B':
			case 'C':
			case 'D':
				int f=*line-'A';
				int d=line[1]-'X';
				if(d<0 || d>=3) break;
				line++;
				int n=1;
				switch(line[1]){
					case '-': n=3; line++; break;
					case '+': n=1; line++; break;
					case '2': n=2; line++; break;
				}
			Rotate(f*3+d,mask,n);
			mask=4;
			break;
		}
	}
}
void main(){
	char s[1000];
	seed=(unsigned long)time(0);
	Init();
	for(;;){
		Show();
		printf("Command: ");
		scanf("%s",s);
		Process(s);
	}
}
