Loesungen des SomaWuerfels, errechnet mit C++ Programm von : Jochen Wermuth: jwermuth(at)freenet.de Die 7 Bloecke stellen die Lage der 7 Bausteine dar. Jeder Block besteht aus 3 Ebenen zuerst oben, dann Mitte, dann unten. Jede Ebene besteht aus 3 mal 3 Zellen. Alle 240 Loesungen nach ausreduzierter Symmetrie werden gefunden!!! // Soma.cpp: Hauptprojektdatei. #include "stdafx.h" #include #include #include using namespace std; using namespace System; using namespace System::IO; struct Wuerfel { Byte W[3][3][3]; // struct-Konstruktor Wuerfel () { for (int i=0; i<3; i++)for (int j=0; j<3; j++)for (int k=0; k<3; k++) Wuerfel::W[i][j][k]= 0; } Wuerfel(Byte W[3][3][3]) { for (int i=0; i<3; i++)for (int j=0; j<3; j++)for (int k=0; k<3; k++) Wuerfel::W[i][j][k]= W[i][j][k]; } }; Wuerfel startWuerfel[4]; Wuerfel TeileDreh[6][24]; Wuerfel falschWuerfel; Wuerfel EinsWuerfel; Wuerfel neuW; Wuerfel Wx; Wuerfel Wy; Wuerfel Wz; Wuerfel W1; Wuerfel W2; Wuerfel W3; Wuerfel W4; Wuerfel W5; Wuerfel W6; Wuerfel W7; Wuerfel dreh(Wuerfel W, char dim); Wuerfel verschieb(Wuerfel W, char dim); int sum (Wuerfel W); int aa; void printWuerfel(Wuerfel W[], int WZahl); void printWuerfel (Wuerfel W); void Mache4Startwuerfel(); void Initialisiere6Teile(); void Rotierkoerper(); bool nochOK(Wuerfel W); bool SumOK(Wuerfel A, Wuerfel B); Wuerfel PlusW(Wuerfel A, Wuerfel B); bool Wgleich (Wuerfel A, Wuerfel B); int main(array ^args) { double AnzBerechnung=1.0; int LsgNr = 1; for (int i=0; i<3; i++)for (int j=0; j<3; j++)for (int k=0; k<3; k++) {falschWuerfel.W[i][j][k] = 9; EinsWuerfel.W[i][j][k] = 1;} StreamWriter^ Somaout; Somaout = gcnew StreamWriter("Somaloesungen.txt", false); Somaout->WriteLine("Loesungen des SomaWuerfels, errechnet mit C++ Programm von :"); Somaout->WriteLine("Jochen Wermuth: jwermuth@freenet.de "); Somaout->WriteLine(" "); Somaout->WriteLine("Die 7 Blöcke stellen die Lage der 7 Bausteine dar."); Somaout->WriteLine("Jeder Block besteht aus 3 Ebenen zuerst oben, dann mitte, dann unten."); Somaout->WriteLine("Jede Ebene besteht aus 3 mal 3 Zellen."); Somaout->WriteLine("Alle 240 Loesungen nach ausreduzierter Symmetrie werden gefunden!!!"); Somaout->WriteLine(" "); Somaout->Close(); Mache4Startwuerfel(); Initialisiere6Teile(); vector *pAlleTeillagen[6]; vector *pAlleTeillagenf[6]; for (int i=0; i<6; i++) {pAlleTeillagen[i] = new vector();pAlleTeillagenf[i] = new vector();} Wuerfel tempW[12]; //jetzt alle Rotierkoerper herstellen Rotierkoerper(); // jetzt Vektoren auffüllen: for (int teilnr = 0; teilnr <6; teilnr++) { for (int rotnr = 0; rotnr <24; rotnr++) { //---------------------------- for (int i=0; i<3; i++) { switch (i) { case 0: Wx = TeileDreh[teilnr][rotnr];break; case 1: Wx = verschieb(TeileDreh[teilnr][rotnr], 'x');break; case 2: Wx = verschieb(TeileDreh[teilnr][rotnr], 'X');break; } aa = Wx.W[1][1][1]; if (aa==9)continue; for (int j=0; j<3; j++) { switch (j) { case 0: Wy= Wx; break; case 1: Wy = verschieb(Wx,'y');break; case 2: Wy = verschieb(Wx, 'Y');break; } aa = Wy.W[1][1][1]; if (aa==9)continue; for (int k=0; k<3; k++) { switch (k) { case 0: Wz = Wy; break; case 1: Wz = verschieb(Wy,'z');break; case 2: Wz = verschieb(Wy, 'Z');break; } aa= Wz.W[1][1][1]; if (aa==9)continue; else pAlleTeillagen[teilnr]->push_back(Wz); } } } //----------------------------------------- } cout << "Vektorgroesse pAlleTeillagen Nr:" << teilnr << " ist : " << pAlleTeillagen[teilnr]->size()<< endl; AnzBerechnung *= double((pAlleTeillagen[teilnr]->size())); } cout << "AnzBerechnung:" << 4* AnzBerechnung/1E12 << " Billionen! \n\n"; AnzBerechnung=1; vector::iterator vNext[6]; vector::iterator vEnd[6]; vector::iterator vNextf[6]; vector::iterator vEndf[6]; for (int teilnr=0; teilnr<6; teilnr++) {vNext[teilnr] = pAlleTeillagen[teilnr]->begin(); vEnd[teilnr] = pAlleTeillagen[teilnr]->end();} //Dubletten Filtern bool drin; for (int teilnr=0; teilnr<6; teilnr++){ for (vNext[teilnr]=pAlleTeillagen[teilnr]->begin();vNext[teilnr] < vEnd[teilnr];vNext[teilnr]++) { drin = false; vEndf[teilnr]=pAlleTeillagenf[teilnr]->end(); for (vNextf[teilnr]=pAlleTeillagenf[teilnr]->begin();vNextf[teilnr] < vEndf[teilnr];vNextf[teilnr]++) { if (Wgleich(vNextf[teilnr]->W, vNext[teilnr]->W)) drin = true; } if (!drin) pAlleTeillagenf[teilnr]->push_back(vNext[teilnr]->W); } cout << "Vektorgroesse pAlleTeillagenf Nr:" << teilnr << " ist : " << pAlleTeillagenf[teilnr]->size()<< endl; AnzBerechnung *= double((pAlleTeillagen[teilnr]->size()));} cout << "AnzBerechnung:" << 4* AnzBerechnung/1E12 << " Billionen! \n\n"; // Ab hier eigentliche Würfelsuche #if 1 int Zaehler=0; for (int teilnr=0; teilnr<6; teilnr++) {vNextf[teilnr] = pAlleTeillagenf[teilnr]->begin(); vEndf[teilnr] = pAlleTeillagenf[teilnr]->end(); } for (int startnr =0; startnr <4; startnr++) { W1 = startWuerfel[startnr]; for (vNextf[0]=pAlleTeillagenf[0]->begin();vNextf[0] < vEndf[0];vNextf[0]++){if (SumOK(W1, vNextf[0]->W)){W2=PlusW(W1, vNextf[0]->W);}else continue; for (vNextf[1]=pAlleTeillagenf[1]->begin();vNextf[1] < vEndf[1];vNextf[1]++){if (SumOK(W2, vNextf[1]->W)){W3=PlusW(W2, vNextf[1]->W);}else continue; for (vNextf[2]=pAlleTeillagenf[2]->begin();vNextf[2] < vEndf[2];vNextf[2]++){if (SumOK(W3, vNextf[2]->W)){W4=PlusW(W3, vNextf[2]->W);}else continue; for (vNextf[3]=pAlleTeillagenf[3]->begin();vNextf[3] < vEndf[3];vNextf[3]++){if (SumOK(W4, vNextf[3]->W)){W5=PlusW(W4, vNextf[3]->W);}else continue; for (vNextf[4]=pAlleTeillagenf[4]->begin();vNextf[4] < vEndf[4];vNextf[4]++){if (SumOK(W5, vNextf[4]->W)){W6=PlusW(W5, vNextf[4]->W);}else continue; for (vNextf[5]=pAlleTeillagenf[5]->begin();vNextf[5] < vEndf[5];vNextf[5]++){if (SumOK(W6, vNextf[5]->W)){W7=PlusW(W6, vNextf[5]->W);}else continue; { cout<< endl<< "Loesung Nr:" << LsgNr << " gefunden" << endl; Somaout = gcnew StreamWriter("Somaloesungen.txt", true); Somaout->Write("Loesung Nr: "); Somaout->Write(LsgNr.ToString()); LsgNr++; Somaout->Close(); tempW[0] = startWuerfel[startnr]; for (int i=1;i<7;i++)tempW[i]= vNextf[i-1]->W;printWuerfel(tempW,7); }}}}}}}} for (int i=0; i<6; i++){pAlleTeillagen[i]->clear(); delete pAlleTeillagen[i];} for (int i=0; i<6; i++){pAlleTeillagenf[i]->clear(); delete pAlleTeillagenf[i];} #endif return 0; } void Mache4Startwuerfel() { for (int i=0; i<3; i++)for (int Wnr=0; Wnr<2; Wnr++) startWuerfel[Wnr].W[i][1][0]=1; // Dorn seitlich : startWuerfel[0].W[0][0][0]=1; // Dorn in Mitte: startWuerfel[1].W[0][1][1]=1; // in Ecke: erst die lange seite, dann Dorn for (int i=0; i<3; i++)startWuerfel[2].W[i][0][0]=1; startWuerfel[2].W[0][1][0]=1; // in Mitte des Wuerfels: for (int i=0; i<3; i++)startWuerfel[3].W[i][1][1]=1; startWuerfel[3].W[0][1][0]=1; } Wuerfel dreh(Wuerfel W,char dim) { Wuerfel TempW; for (int i=0; i<3; i++)for (int j=0; j<3; j++)for (int k=0; k<3; k++) TempW.W[i][j][k] = W.W[i][j][k]; switch (dim) { case 'x': for (int i=0; i<3; i++) { W.W[i][0][1] = TempW.W[i][1][2]; W.W[i][1][2] = TempW.W[i][2][1]; W.W[i][2][1] = TempW.W[i][1][0]; W.W[i][1][0] = TempW.W[i][0][1]; W.W[i][0][0] = TempW.W[i][0][2]; W.W[i][0][2] = TempW.W[i][2][2]; W.W[i][2][2] = TempW.W[i][2][0]; W.W[i][2][0] = TempW.W[i][0][0]; } break; case 'y': for (int i=0; i<3; i++) { W.W[0][i][1] = TempW.W[1][i][2]; W.W[1][i][2] = TempW.W[2][i][1]; W.W[2][i][1] = TempW.W[1][i][0]; W.W[1][i][0] = TempW.W[0][i][1]; W.W[0][i][0] = TempW.W[0][i][2]; W.W[0][i][2] = TempW.W[2][i][2]; W.W[2][i][2] = TempW.W[2][i][0]; W.W[2][i][0] = TempW.W[0][i][0]; } break; case 'z': for (int i=0; i<3; i++) { W.W[0][1][i] = TempW.W[1][2][i]; W.W[1][2][i] = TempW.W[2][1][i]; W.W[2][1][i] = TempW.W[1][0][i]; W.W[1][0][i] = TempW.W[0][1][i]; W.W[0][0][i] = TempW.W[0][2][i]; W.W[0][2][i] = TempW.W[2][2][i]; W.W[2][2][i] = TempW.W[2][0][i]; W.W[2][0][i] = TempW.W[0][0][i]; } break; } return W; } void Rotierkoerper() { for (int teilnr = 0; teilnr <6; teilnr++) { int rotationsNr = 0; for (int yNr = 0; yNr<4; yNr++) { TeileDreh[teilnr][rotationsNr]= dreh(TeileDreh[teilnr][rotationsNr],'y'); for (int zNr = 0; zNr<4; zNr++) { TeileDreh[teilnr][rotationsNr+1]= dreh(TeileDreh[teilnr][rotationsNr],'z'); rotationsNr++; } } TeileDreh[teilnr][rotationsNr]= dreh(TeileDreh[teilnr][0],'x'); for (int zNr = 0; zNr<3; zNr++) { TeileDreh[teilnr][rotationsNr+1]= dreh(TeileDreh[teilnr][rotationsNr],'z'); rotationsNr++; } rotationsNr++; TeileDreh[teilnr][rotationsNr]= dreh(TeileDreh[teilnr][0],'x'); TeileDreh[teilnr][rotationsNr]= dreh(TeileDreh[teilnr][rotationsNr],'x'); TeileDreh[teilnr][rotationsNr]= dreh(TeileDreh[teilnr][rotationsNr],'x'); for (int zNr = 0; zNr<3; zNr++) { TeileDreh[teilnr][rotationsNr+1]= dreh(TeileDreh[teilnr][rotationsNr],'z'); rotationsNr++; } cout <<"rotationsnr :" << rotationsNr << " TNr : " << teilnr <WriteLine(" "); int ii; for (int k=2; k>-1; k--){ for (int j=2; j>-1; j--) {for (int Wnr=0; WnrWrite(" "); for (int i=0; i<3; i++) {ii=(int)W[Wnr].W[i][j][k];cout << ii; SomaoutpW->Write(ii+48);}}; cout <WriteLine(" ");};cout <WriteLine(" ");} SomaoutpW->WriteLine(" "); SomaoutpW->Close(); } void printWuerfel (Wuerfel W) { for (int k=2; k>-1; k--){ for (int j=2; j>-1; j--){ {for (int i=0; i<3; i++)cout << (int)W.W[i][j][k];} cout <1) OK = false; return OK; } Wuerfel PlusW(Wuerfel A, Wuerfel B) { Wuerfel C; for (int i=0; i<3; i++)for (int j=0; j<3; j++)for (int k=0; k<3; k++) { C.W[i][j][k]=A.W[i][j][k]+B.W[i][j][k]; } return C; } bool SumOK(Wuerfel A, Wuerfel B) { Wuerfel C; C = PlusW(A,B); return nochOK(C); }