/*
*	Program:     Crazy Turtle Solver utility
*	Version:     1.0
*	Language:    ANSI C
*	Screen:      80 columns output
*	Platform:    UNIX, Linux, DOS/Windows
*	Development: cross-compiled and tested on Linux
*
*	Compile:     gcc -O3 ctsolve.c -o ctsolve                    // UNIX, Linux
*	Run:         ./ctsolve 436313711407564402360467264555227520  // UNIX, Linux
*
*       Compile:     tcc -G ctsolve.c                                // DOS/Windows
*       Run:         ctsolve 436313711407564402360467264555227520    // DOS/Windows
*
*	Author:      Eduard Zenzerovic (ezenzero@hotmail.com)
*/

#include <stdio.h>
#include <string.h>

unsigned int turtle[9][4];

unsigned int A1 [4][2];
unsigned int A2[32][2];
unsigned int A3 [4][2];
unsigned int B1[32][2];
unsigned int B3[32][2];
unsigned int C1 [4][2];
unsigned int C2[32][2];
unsigned int C3 [4][2];


int main(int argc, char* argv[]){

	unsigned int B2 = 0;
	unsigned int A2count = 0;
	unsigned int B3count = 0;
	unsigned int C2count = 0;
	unsigned int B1count = 0;
	unsigned int A2Eseek = 0;
	unsigned int B3Sseek = 0;
	unsigned int C2Wseek = 0;
	unsigned int B1Nseek = 0;

	unsigned int A3count = 0;
	unsigned int C3count = 0;
	unsigned int C1count = 0;
	unsigned int A1count = 0;

	unsigned int A3Sseek = 0;
	unsigned int A3Eseek = 0;
	unsigned int C3Wseek = 0;
	unsigned int C3Sseek = 0;
	unsigned int C1Nseek = 0;
	unsigned int C1Wseek = 0;
	unsigned int A1Eseek = 0;
	unsigned int A1Nseek = 0;

	unsigned int a = 0;
	unsigned int b = 0;
	unsigned int c = 0;
	unsigned int d = 0;
	unsigned int e = 0;

	unsigned int x = 0;
	unsigned int y = 0;
	unsigned int z = 0;
	unsigned int w = 0;

	unsigned int i = 0;
	unsigned int j = 0;

	unsigned int k = 0;
	unsigned int l = 0;
	unsigned int m = 0;
	unsigned int n = 0;

	unsigned int numberofsolutions = 0;

	if(argc!=2) {
		printf("\n");
		printf("Usage example:\n\n");
		printf("      ctsolve 436313711407564402360467264555227520\n");
		printf("              ||||||||||||||||||||||||||||||||||||\n");
		printf("              LTRBLTRBLTRBLTRBLTRBLTRBLTRBLTRBLTRB\n");
		printf("              |__||__||__||__||__||__||__||__||__|\n");
		printf("Card Number:    1   2   3   4   5   6   7   8   9\n\n");
		printf("Legend:\n\n");
   		printf("RED/ORANGE    HEAD = 0   RED    BACK = 4     L - LEFT     +---------------+\n");
		printf("GREEN         HEAD = 1   GREEN  BACK = 5     T - TOP      |      TOP      |\n");
		printf("BLUE          HEAD = 2   BLUE   BACK = 6     R - RIGHT    | LEFT    RIGHT |\n");
		printf("YELLOW/PURPLE HEAD = 3   YELLOW BACK = 7     B - BOTTOM   |    BOTTOM     |\n");
		printf("                                                          +---------------+\n");
		printf("Solution:     c->r  c-card number\n");
		printf("                    r-rotation in clockwise direction\n\n");
		printf("              rotation 0 =  no rotation\n");
		printf("              rotation 1 =  90 degree in clockwise direction or one step\n");
		printf("              rotation 2 = 180 degree in clockwise direction or two steps\n");
		printf("              rotation 3 = 270 degree in clockwise direction or three steps\n\n");
		printf("              4->1  would mean Card Number 4 that we have to\n");
		printf("                    rotate clockwise for 90 degrees\n\n");
		printf("Author:       Eduard Zenzerovic (ezenzero@hotmail.com)\n\n");
		return 0;
	}

	if(strlen(argv[1])!=36) {
		printf("\nYour string of numbers has %i digits.\nString of numbers should have 9 cards * 4 digits = 36 digits!\n\n", strlen(argv[1]));
		printf("Author:       Eduard Zenzerovic (ezenzero@hotmail.com)\n\n");
		return 0;
	}

	for(c=0,e=0; c<9; c++){
		for(d=0; d<4; d++){
			switch(argv[1][e++]){
				case '0':
					turtle[c][d] = 0;
					break;
				case '1':
					turtle[c][d] = 1;
					break;
				case '2':
					turtle[c][d] = 2;
					break;
				case '3':
					turtle[c][d] = 3;
					break;
				case '4':
					turtle[c][d] = 4;
					break;
				case '5':
					turtle[c][d] = 5;
					break;
				case '6':
					turtle[c][d] = 6;
					break;
				case '7':
					turtle[c][d] = 7;
					break;
				default:
					printf("\nDigits are: 0,1,2,3,4,5,6 and 7\n\n");
					printf("Author: Eduard Zenzerovic (ezenzero@hotmail.com)\n\n");
					return 0;
			}
		}
	}

	for(B2=0; B2<9; B2++){
		
		A2count=0;
		B3count=0;
		C2count=0;
		B1count=0;

		A2Eseek = turtle[B2][0]^4;
		B3Sseek = turtle[B2][1]^4;
		C2Wseek = turtle[B2][2]^4;
		B1Nseek = turtle[B2][3]^4;

		for(a=0; a<9; a++){
			if(a==B2) continue;
			for(b=0; b<4; b++){
				if(turtle[a][b]==A2Eseek) {
					A2[A2count][0] = a;
					A2[A2count][1] = b;
					A2count++;
				}
				if(turtle[a][b]==B3Sseek) {
					B3[B3count][0] = a;
					B3[B3count][1] = b;
					B3count++;
				}
				if(turtle[a][b]==C2Wseek) {
					C2[C2count][0] = a;
					C2[C2count][1] = b;
					C2count++;
				}
				if(turtle[a][b]==B1Nseek) {
					B1[B1count][0] = a;
					B1[B1count][1] = b;
					B1count++;
				}
			}
		}

		for(x=0;x<A2count;x++){
			for(y=0;y<B3count;y++){
				if(B3[y][0]==A2[x][0]) continue;
				for(z=0;z<C2count;z++){
					if((C2[z][0]==B3[y][0]) || (C2[z][0]==A2[x][0])) continue;
					for(w=0;w<B1count;w++){

						if((B1[w][0]==C2[z][0]) || (B1[w][0]==B3[y][0]) || (B1[w][0]==A2[x][0])) continue;

						A3count=0;
						C3count=0;
						C1count=0;
						A1count=0;

						for(i=0; i<9; i++){

							if((i==B2) || (i==A2[x][0]) || (i==B3[y][0]) || (i==C2[z][0]) || (i==B1[w][0])) continue;

							A3Sseek = (turtle[A2[x][0]][(A2[x][1]==0)?(3):(A2[x][1]-1)])^4;
							A3Eseek = (turtle[B3[y][0]][(B3[y][1]==3)?(0):(B3[y][1]+1)])^4;
							C3Wseek = (turtle[B3[y][0]][(B3[y][1]==0)?(3):(B3[y][1]-1)])^4;
							C3Sseek = (turtle[C2[z][0]][(C2[z][1]==3)?(0):(C2[z][1]+1)])^4;
							C1Nseek = (turtle[C2[z][0]][(C2[z][1]==0)?(3):(C2[z][1]-1)])^4;
							C1Wseek = (turtle[B1[w][0]][(B1[w][1]==3)?(0):(B1[w][1]+1)])^4;
							A1Eseek = (turtle[B1[w][0]][(B1[w][1]==0)?(3):(B1[w][1]-1)])^4;
							A1Nseek = (turtle[A2[x][0]][(A2[x][1]==3)?(0):(A2[x][1]+1)])^4;

							for(j=0; j<4; j++){
								if((turtle[i][j]==A3Sseek) && (turtle[i][(j==0)?3:j-1]==A3Eseek)) {
									A3[A3count][0] = i;
									A3[A3count][1] = j;
									A3count++;
								}
								if((turtle[i][j]==C3Wseek) && (turtle[i][(j==0)?3:j-1]==C3Sseek)) {
									C3[C3count][0] = i;
									C3[C3count][1] = j;
									C3count++;
								}
								if((turtle[i][j]==C1Nseek) && (turtle[i][(j==0)?3:j-1]==C1Wseek)) {
									C1[C1count][0] = i;
									C1[C1count][1] = j;
									C1count++;
								}
								if((turtle[i][j]==A1Eseek) && (turtle[i][(j==0)?3:j-1]==A1Nseek)) {
									A1[A1count][0] = i;
									A1[A1count][1] = j;
									A1count++;
								}
							}
						}

						if(A3count && C3count && C1count && A1count) {
							for(k=0;k<A3count;k++){
								for(l=0;l<C3count;l++){
									if(C3[l][0]==A3[k][0]) continue;
									for(m=0;m<C1count;m++){
										if((C1[m][0]==C3[l][0]) || (C1[m][0]==A3[k][0])) continue;
										for(n=0;n<A1count;n++){
											if((A1[n][0]==C1[m][0]) || (A1[n][0]==C3[l][0]) || (A1[n][0]==A3[k][0])) continue;

				
											printf("\n [%i. solution]\n\n",++numberofsolutions);

											printf(" %i->%i | ",   A3[k][0]+1, A3[k][1]==0?3:A3[k][1]==1?2:A3[k][1]==2?1:0);
											printf("%i->%i | ",    B3[y][0]+1, B3[y][1]==0?3:B3[y][1]==1?2:B3[y][1]==2?1:0);
											printf("%i->%i\n",     C3[l][0]+1, C3[l][1]==0?0:C3[l][1]==1?3:C3[l][1]==2?2:1);
											printf("------+------+------\n");
											printf(" %i->%i | ",   A2[x][0]+1, A2[x][1]==0?2:A2[x][1]==1?1:A2[x][1]==2?0:3);
											printf("%i->%i | ",    B2+1,                                                 0);
											printf("%i->%i\n",     C2[z][0]+1, C2[z][1]==0?0:C2[z][1]==1?3:C2[z][1]==2?2:1);
											printf("------+------+------\n");
											printf(" %i->%i | ",   A1[n][0]+1, A1[n][1]==0?2:A1[n][1]==1?1:A1[n][1]==2?0:3);
											printf("%i->%i | ",    B1[w][0]+1, B1[w][1]==0?1:B1[w][1]==1?0:B1[w][1]==2?3:2);
											printf("%i->%i\n",     C1[m][0]+1, C1[m][1]==0?1:C1[m][1]==1?0:C1[m][1]==2?3:2);

											printf("\n %i->%i | ", A1[n][0]+1, ((A1[n][1]==0?2:A1[n][1]==1?1:A1[n][1]==2?0:3)+1)>3?(((A1[n][1]==0?2:A1[n][1]==1?1:A1[n][1]==2?0:3)+1)-4):(((A1[n][1]==0?2:A1[n][1]==1?1:A1[n][1]==2?0:3)+1)));
											printf("%i->%i | ",    A2[x][0]+1, ((A2[x][1]==0?2:A2[x][1]==1?1:A2[x][1]==2?0:3)+1)>3?(((A2[x][1]==0?2:A2[x][1]==1?1:A2[x][1]==2?0:3)+1)-4):(((A2[x][1]==0?2:A2[x][1]==1?1:A2[x][1]==2?0:3)+1)));
											printf("%i->%i\n",     A3[k][0]+1, ((A3[k][1]==0?3:A3[k][1]==1?2:A3[k][1]==2?1:0)+1)>3?(((A3[k][1]==0?3:A3[k][1]==1?2:A3[k][1]==2?1:0)+1)-4):(((A3[k][1]==0?3:A3[k][1]==1?2:A3[k][1]==2?1:0)+1)));
											printf("------+------+------\n");
											printf(" %i->%i | ",   B1[w][0]+1, ((B1[w][1]==0?1:B1[w][1]==1?0:B1[w][1]==2?3:2)+1)>3?(((B1[w][1]==0?1:B1[w][1]==1?0:B1[w][1]==2?3:2)+1)-4):(((B1[w][1]==0?1:B1[w][1]==1?0:B1[w][1]==2?3:2)+1)));
											printf("%i->%i | ",    B2+1,                                                                                                                                                                   1);
											printf("%i->%i\n",     B3[y][0]+1, ((B3[y][1]==0?3:B3[y][1]==1?2:B3[y][1]==2?1:0)+1)>3?(((B3[y][1]==0?3:B3[y][1]==1?2:B3[y][1]==2?1:0)+1)-4):(((B3[y][1]==0?3:B3[y][1]==1?2:B3[y][1]==2?1:0)+1)));
											printf("------+------+------\n");
											printf(" %i->%i | ",   C1[m][0]+1, ((C1[m][1]==0?1:C1[m][1]==1?0:C1[m][1]==2?3:2)+1)>3?(((C1[m][1]==0?1:C1[m][1]==1?0:C1[m][1]==2?3:2)+1)-4):(((C1[m][1]==0?1:C1[m][1]==1?0:C1[m][1]==2?3:2)+1)));
											printf("%i->%i | ",    C2[z][0]+1, ((C2[z][1]==0?0:C2[z][1]==1?3:C2[z][1]==2?2:1)+1)>3?(((C2[z][1]==0?0:C2[z][1]==1?3:C2[z][1]==2?2:1)+1)-4):(((C2[z][1]==0?0:C2[z][1]==1?3:C2[z][1]==2?2:1)+1)));
											printf("%i->%i\n",     C3[l][0]+1, ((C3[l][1]==0?0:C3[l][1]==1?3:C3[l][1]==2?2:1)+1)>3?(((C3[l][1]==0?0:C3[l][1]==1?3:C3[l][1]==2?2:1)+1)-4):(((C3[l][1]==0?0:C3[l][1]==1?3:C3[l][1]==2?2:1)+1)));

											printf("\n %i->%i | ", C1[m][0]+1, ((C1[m][1]==0?1:C1[m][1]==1?0:C1[m][1]==2?3:2)+2)>3?(((C1[m][1]==0?1:C1[m][1]==1?0:C1[m][1]==2?3:2)+2)-4):(((C1[m][1]==0?1:C1[m][1]==1?0:C1[m][1]==2?3:2)+2)));
											printf("%i->%i | ",    B1[w][0]+1, ((B1[w][1]==0?1:B1[w][1]==1?0:B1[w][1]==2?3:2)+2)>3?(((B1[w][1]==0?1:B1[w][1]==1?0:B1[w][1]==2?3:2)+2)-4):(((B1[w][1]==0?1:B1[w][1]==1?0:B1[w][1]==2?3:2)+2)));
											printf("%i->%i\n",     A1[n][0]+1, ((A1[n][1]==0?2:A1[n][1]==1?1:A1[n][1]==2?0:3)+2)>3?(((A1[n][1]==0?2:A1[n][1]==1?1:A1[n][1]==2?0:3)+2)-4):(((A1[n][1]==0?2:A1[n][1]==1?1:A1[n][1]==2?0:3)+2)));
											printf("------+------+------\n");
											printf(" %i->%i | ",   C2[z][0]+1, ((C2[z][1]==0?0:C2[z][1]==1?3:C2[z][1]==2?2:1)+2)>3?(((C2[z][1]==0?0:C2[z][1]==1?3:C2[z][1]==2?2:1)+2)-4):(((C2[z][1]==0?0:C2[z][1]==1?3:C2[z][1]==2?2:1)+2)));
											printf("%i->%i | ",    B2+1,                                                                                                                                                                   2);
											printf("%i->%i\n",     A2[x][0]+1, ((A2[x][1]==0?2:A2[x][1]==1?1:A2[x][1]==2?0:3)+2)>3?(((A2[x][1]==0?2:A2[x][1]==1?1:A2[x][1]==2?0:3)+2)-4):(((A2[x][1]==0?2:A2[x][1]==1?1:A2[x][1]==2?0:3)+2)));
											printf("------+------+------\n");
											printf(" %i->%i | ",   C3[l][0]+1, ((C3[l][1]==0?0:C3[l][1]==1?3:C3[l][1]==2?2:1)+2)>3?(((C3[l][1]==0?0:C3[l][1]==1?3:C3[l][1]==2?2:1)+2)-4):(((C3[l][1]==0?0:C3[l][1]==1?3:C3[l][1]==2?2:1)+2)));
											printf("%i->%i | ",    B3[y][0]+1, ((B3[y][1]==0?3:B3[y][1]==1?2:B3[y][1]==2?1:0)+2)>3?(((B3[y][1]==0?3:B3[y][1]==1?2:B3[y][1]==2?1:0)+2)-4):(((B3[y][1]==0?3:B3[y][1]==1?2:B3[y][1]==2?1:0)+2)));
											printf("%i->%i\n",     A3[k][0]+1, ((A3[k][1]==0?3:A3[k][1]==1?2:A3[k][1]==2?1:0)+2)>3?(((A3[k][1]==0?3:A3[k][1]==1?2:A3[k][1]==2?1:0)+2)-4):(((A3[k][1]==0?3:A3[k][1]==1?2:A3[k][1]==2?1:0)+2)));

											printf("\n %i->%i | ", C3[l][0]+1, ((C3[l][1]==0?0:C3[l][1]==1?3:C3[l][1]==2?2:1)+3)>3?(((C3[l][1]==0?0:C3[l][1]==1?3:C3[l][1]==2?2:1)+3)-4):(((C3[l][1]==0?0:C3[l][1]==1?3:C3[l][1]==2?2:1)+3)));
											printf("%i->%i | ",    C2[z][0]+1, ((C2[z][1]==0?0:C2[z][1]==1?3:C2[z][1]==2?2:1)+3)>3?(((C2[z][1]==0?0:C2[z][1]==1?3:C2[z][1]==2?2:1)+3)-4):(((C2[z][1]==0?0:C2[z][1]==1?3:C2[z][1]==2?2:1)+3)));
											printf("%i->%i\n",     C1[m][0]+1, ((C1[m][1]==0?1:C1[m][1]==1?0:C1[m][1]==2?3:2)+3)>3?(((C1[m][1]==0?1:C1[m][1]==1?0:C1[m][1]==2?3:2)+3)-4):(((C1[m][1]==0?1:C1[m][1]==1?0:C1[m][1]==2?3:2)+3)));
											printf("------+------+------\n");
											printf(" %i->%i | ",   B3[y][0]+1, ((B3[y][1]==0?3:B3[y][1]==1?2:B3[y][1]==2?1:0)+3)>3?(((B3[y][1]==0?3:B3[y][1]==1?2:B3[y][1]==2?1:0)+3)-4):(((B3[y][1]==0?3:B3[y][1]==1?2:B3[y][1]==2?1:0)+3)));
											printf("%i->%i | ",    B2+1,                                                                                                                                                                   3);
											printf("%i->%i\n",     B1[w][0]+1, ((B1[w][1]==0?1:B1[w][1]==1?0:B1[w][1]==2?3:2)+3)>3?(((B1[w][1]==0?1:B1[w][1]==1?0:B1[w][1]==2?3:2)+3)-4):(((B1[w][1]==0?1:B1[w][1]==1?0:B1[w][1]==2?3:2)+3)));
											printf("------+------+------\n");
											printf(" %i->%i | ",   A3[k][0]+1, ((A3[k][1]==0?3:A3[k][1]==1?2:A3[k][1]==2?1:0)+3)>3?(((A3[k][1]==0?3:A3[k][1]==1?2:A3[k][1]==2?1:0)+3)-4):(((A3[k][1]==0?3:A3[k][1]==1?2:A3[k][1]==2?1:0)+3)));
											printf("%i->%i | ",    A2[x][0]+1, ((A2[x][1]==0?2:A2[x][1]==1?1:A2[x][1]==2?0:3)+3)>3?(((A2[x][1]==0?2:A2[x][1]==1?1:A2[x][1]==2?0:3)+3)-4):(((A2[x][1]==0?2:A2[x][1]==1?1:A2[x][1]==2?0:3)+3)));
											printf("%i->%i\n",     A1[n][0]+1, ((A1[n][1]==0?2:A1[n][1]==1?1:A1[n][1]==2?0:3)+3)>3?(((A1[n][1]==0?2:A1[n][1]==1?1:A1[n][1]==2?0:3)+3)-4):(((A1[n][1]==0?2:A1[n][1]==1?1:A1[n][1]==2?0:3)+3)));

										}
									}
								}
							}
						}

					}
				}
			}
		}
	};

	if(numberofsolutions==0){
		printf("\nNo solutions found.");
	}
	printf("\n\nAuthor: Eduard Zenzerovic (ezenzero@hotmail.com)\n\n");

 	return 0;
}