Tetris kubus bijna gekraakt. Computer houdt het niet meer..

Status
Niet open voor verdere reacties.

Quadra

Gebruiker
Lid geworden
17 jun 2009
Berichten
7
Een goeiemiddag,

Sinds kort heb ik de draad met C++ weer opgepakt en heb besloten om te kijken hoeveel oplossingen er mogelijk zijn voor de Tetris kubus.

Tot mijn grote verbazing is het programma af. Het bestaat uit een paar honderd for(..) lussen en is byzonder complex. Hier een korte uitleg:

De tetris kubus heeft 12 stukken. Eerst heb ik van alle stukken de mogelijkheden nagegaan en die in 2dimensionale arrays gestopt. van a[x][y] tot m[x][y] (die van i overgeslagen). De x betekend dan de hoeveelste manier het is hoe het stuk kan zitten, en de y is een getal tussen de 0 en de 63.

Nouwjah; dat ging allemaal prima alleen was het wel intensief werk. Nu heb ik dus alle verschillende manieren door middel van getalletjes opgeslagen en moet er alleen nog zien uit te vogelen wanneer alle getallen tegelijkertijd 1 zijn. (dan zit niets over elkaar heen of mist er ergens wat)

En hierbij loopt mijn computer om de haverklap vast..
Eerst had ik dit, dit deed het overigens wel, alleen zou mijn computer zou er een paar miljoen jaar over doen, dat was met deze code:



Code:
int jj, kk, ll, mm;
//OPLOSSING ZOEKEN
for(int aa=0;aa<(xa+1);aa++){
for(int bb=0;bb<(xb+1);bb++){
for(int cc=0;cc<(xc+1);cc++){
for(int dd=0;dd<(xd+1);dd++){        
for(int ee=0;ee<(xe+1);ee++){
for(int ff=0;ff<(xf+1);ff++){
for(int gg=0;gg<(xg+1);gg++){
for(int hh=0;hh<(xh+1);hh++){
cout << "xa: " << aa << " xb: " << bb << " xc: " << cc << " xd: " << dd  << " xe: " << ee << " xf: " << ff << " xg: " << gg << " xh: " << hh  << " xj: " << jj << " xk: " << kk << " xl: " << ll << " xm: " << mm  << "\n";
for(jj=0;jj<(xj+1);jj++){
for(kk=0;kk<(xk+1);kk++){
for(ll=0;ll<(xl+1);ll++){
for(mm=0;mm<(xm+1);mm++){
        
        //alles samenvoegen    
        y=0;
        while ((y < 65) && (oke))
        {
        t[y]= a[aa][y] + b[bb][y] + c[cc][y] + d[dd][y] + e[ee][y] + f[ff][y] + g[gg][y] + h[hh][y] + j[jj][y] + k[kk][y] + l[ll][y] + m[mm][y];

        if(t[y] != 1){oke=false;}
        y++;
        }//einde while lus

if(oke){
system("cls");
cout << "xa = " << aa << "\n\n";
cout << "xb = " << bb << "\n\n";
cout << "xc = " << cc << "\n\n";
cout << "xd = " << dd << "\n\n";
cout << "xe = " << ee << "\n\n";
cout << "xf = " << ff << "\n\n";
cout << "xg = " << gg << "\n\n";
cout << "xh = " << hh << "\n\n";
cout << "xj = " << jj << "\n\n";
cout << "xk = " << kk << "\n\n";
cout << "xl = " << ll << "\n\n";
cout << "xm = " << mm << "\n\n";
cin.get();
}

if(!oke){
oke=true;}
}

}}}}}}}}}}}


Nouwjah.. daar werd ik dus niet blij van dus heb wat anders verzonnen:
Dat was meer iets van elke keer 3 stukken bij elkaar zoeken; de mogelijkheden daarvan in 1 variabele stoppen en later die 4 variabelen (lomp grote arrays) optellen. Dat is dit:









int mog_l[100000]; // 
unsigned long bit=0;
for(int kk=0;kk<(xk+1);kk++){
for(int ll=0;ll<(xl+1);ll++){
for(int mm=0;mm<(xm+1);mm++){
        
        
oke=true;       
for(int q=0;q<65;q++)
{
        if((k[kk][q] + m[mm][q] + l[ll][q]) > 1){ 
        oke=false;}
}//einde for voor de 64 lus

if(oke){ 

mog_l[bit]=kk;
bit++;
mog_l[bit]=ll;
bit++;
mog_l[bit]=mm;
bit++;   
}    

}// m lus
}//einde l lus
}//end of k
cout << bit << endl;
cin.get();













int mog_h[200000]; // 
bit=0;
for(int jj=0;jj<(xj+1);jj++){
for(int hh=0;hh<(xh+1);hh++){
for(int gg=0;gg<(xg+1);gg++){
        
        
oke=true;       
for(int q=0;q<65;q++)
{
        if((j[jj][q] + h[hh][q] + g[gg][q]) > 1){ 
        oke=false;}
}//einde for voor de 64 lus

if(oke){ 
mog_h[bit]=gg;
bit++;
mog_h[bit]=hh;
bit++;
mog_h[bit]=jj;
bit++;   
}    

}// m lus
}//einde l lus
}//end of k



cout << bit << endl;
cin.get();










int mog_d[100000]; // 
bit=0;
for(int dd=0;dd<(xd+1);dd++){
for(int ee=0;ee<(xe+1);ee++){
for(int ff=0;ff<(xf+1);ff++){
        
        
oke=true;       
for(int q=0;q<65;q++)
{
        if((d[dd][q] + e[ee][q] + f[ff][q]) > 1){ 
        oke=false;}
}//einde for voor de 64 lus

if(oke){ 
mog_d[bit]=dd;
bit++;
mog_d[bit]=ee;
bit++;
mog_d[bit]=ff;
bit++;   
}    

}// m lus
}//einde l lus
}//end of k



cout << bit << endl;
cin.get();








cout << xa << " " << xb << " " << xc << endl;
cin.get();

int mog_a[100000]; // 
bit=0;
for(int aa=0;aa<(xa+1);aa++){
for(int bb=0;bb<(xb+1);bb++){
for(int cc=0;cc<(xc+1);cc++){
        
        
oke=true;       
for(int q=0;q<65;q++)
{
        if((a[aa][q] + b[bb][q] + c[cc][q]) > 1){ 
        oke=false;}
}//einde for voor de 64 lus

if(oke){ 
mog_a[bit]=aa;
bit++;
mog_a[bit]=bb;
bit++;
mog_a[bit]=cc;
bit++;   
}    

}// m lus
}//einde l lus
}//end of k
cout << bit << endl;
cin.get();















//BITS
//31527
//30263 (90075)
//104697 (47122)
//69

//BITS
//79832
//30263 (90075)
//104697 (47122)
//305470



//
cout << "eerste keer:\n";
cin.get();

bit=0;   
for(int aa=0;(mog_a[aa])<(xa+1);(aa=aa+3)){ 
cout << aa;      
for(int dd=0;(mog_d[dd])<(xd+1);(dd=dd+3)){       
oke=true;   

           
for(int q=0;q<65;q++)
{
        if(( a[(mog_a[aa])][q] + b[(mog_a[(aa+1)])][q] + c[(mog_a[(aa+2)])][q] + d[(mog_d[dd])][q] + e[(mog_d[(dd+1)])][q] + f[(mog_d[(dd+2)])][q]) > 1){ 
        oke=false;}
}//einde for voor de 64 lus
bit++;
if(oke){ 
cout << "WE GOT IT";
cin.get();}

cout << bit;
}}






Hier tel ik maar 2 variabelen op, maar ook dit doet het niet.. wat de computer doet:
- Vastlopen
- Vanzelf uitschakelen

Dus ik vraag me af wat er aan de hand is..
Waar ik nu naar op zoek ben..

Hoe groot kunnen arrays worden?
Hoe maak ik dit programma sneller en beter?

En natuurlijk komt hier de complete code nog:
Code
 
Laatst bewerkt door een moderator:
Hier heb ik dus weinig aan..
het gaat erom dat het gewoon TE LANG duurt zo.. en als hij vastloopt komt dat omdat ik met TE GROTE getallen/variabelen werk..

maar weet iemand dan iets om dit in te palmen?
 
Hier heb ik dus weinig aan..
het gaat erom dat het gewoon TE LANG duurt zo.. en als hij vastloopt komt dat omdat ik met TE GROTE getallen/variabelen werk..

maar weet iemand dan iets om dit in te palmen?

Dan moet je je vraag anders stellen...
Verder is het normaal, het is een puzzel die er gemaakt is om miljoenen verschillende mogelijkheden te hebben. Als jij het dan wilt brute forcen dat duurt dat nou eenmaal lang.
Je moet dus een slim algorithme maken.
 
Precies, jouw code heeft een hele grote complexiteit. Hoe meer for-lussen in elkaar, hoe groter de complexiteit en hoe langer het duurt om de oplossing te vinden. Je zult dus eerst moeten bedenken hoe het efficiënter kan en die oplossing dan programmeren.
 
lieve mensen,

heel erg bedankt voor jullie reacties.. maar de vraag die jullie oproepen is exact dezelfde als die ik bedoelde te stellen:

Hoe krijg ik die code zo efficient mogelijk, dus niet teveel for-lussen bij elkaar, en dat hij er toch ooit eens uitkomt he..?
 
Wat je eigenlijk zou moeten proberen is om een model te maken voor de puzzel. Je hebt dan dus het 'speelveld' van 4x4x4 vakjes en de 'stukken'.

In het begin is het speelveld 'leeg'. Je kunt dan gaan proberen om de stukken erop te plaatsen. Voor het eerste stuk heb je dus al heel veel mogelijkheden:
- aantal stukken (bijvoorbeeld x stukken)
- het aantal posities waarop het stuk op het speelveld geplaatst kan worden (bijvoorbeeld y posities)
- alle rotaties van het stuk (je hebt rotaties om 3 assen, dus dat zijn er ook heel wat, bijvoorbeeld z)

Voor de eerste 'zet' heb je dus al x x y x z mogelijkheden!

Je kunt dan een array opbouwen met al deze mogelijkheden en per 'nieuw speelveld' (dus met 1 stuk erop) kun je dan weer hetzelfde gaan doen. Het aantal mogelijke 'zetten' wordt dan wel minder, omdat er al 1 stuk op het speelveld staat.

Wat misschien makkelijker is om te proberen is het spelletje Solitaire te maken. Je hebt dan namelijk maar met een 2D speelveld te maken ipv 3D en bovendien heb je maar 1 soort stukken. Om dit spel binnen redelijke tijd op te lossen heb je ook al behoorlijk veel rekenkracht nodig, dus ook hier zul je slim moeten zijn. Een gespiegeld bord heeft immers precies dezelfde mogelijkheden als zijn origineel (maar hoe weet je of een bord gespiegeld is...?). Genoeg uitdaging dus ;)

Succes!
 
Ah.. ik ben blij dat we tot dezelfde conclusie gekomen.
Ik heb dus van al die 12 stukken alle mogelijkheden in een array gezet..
per stuk waren er zo'n 60 tot 220 mogelijkheden. De arrays beginnen met een letter..
en dan de eerste dimensie is de mogelijkheid (van 0 tot 219 bijv.) en de 2e is op welke plaats dat ding zich in de kubus vind. Is de waarde 1, dan is daar een deel van het stuk.

Nu kunnen we dat op een aantal mogelijkheden proberen uit te vogelen:
1. in 12 for-lussen alles testen
Probleem: duurt een aantal miljoen jaar ofzo, met mijn computer..

Toen kwam het volgende idee op. Bij bijvoorbeeld alleen stuk 1 en 2 vallen al de helft van de mogelijkheden af.. als je dat op de een of andere manier kan onthouden.. dan ga je al een stuk sneller.. Maar de vraag hoe ik dat dan moet doen..
2.1 eerst de eerste 2 a 4 stukken doen en dan telkens er een stuk bij
Probleem: computer loopt vast
2.2 4 lomp grote arrays met elk 3 stukken en uiteindelijk die in 4 for lussen vergelijken
Probleem: te grote arrays/integers vermoed ik..

Maar ergens in mn achterhoofd broeit DE oplossing.. alleen kan ik em nog niet vinden..
Toevallig een geniale insteek (of een manier om 6dimensionale arrays te maken)?
 
Je hebt eigenlijk alleen maar een 3 dimensionale array nodig: bord[4][4][4].
Vervolgens geef je elk van de stukken een nummer (dus bij 8 stukken heb je 1 t/m 8). In de 3 dimensionale array zet je dan op een positie de nummer van het stuk als die plaats door het stuk bezet wordt gehouden. Een 0 betekent afwezigheid van een stuk.

Maar nogmaals, dit is vrij lastig, omdat je er rekening mee moet houden dat de stukken altijd de goede vorm hebben. Solitaire eerst proberen is al lastig genoeg.
 
Ehh, waar moet ik rekening mee houden?
Ik heb juist voor elk stuk alle mogelijkheden gedefinieerd.. deels door gewoon invoeren, deels door programmeren.. en al die mogelijkheden test tie bij elkaar..
 
Waar je overal rekening mee moet houden? Hoe bedoel je dat?
Je moet eerst zorgen dat je een goed model hebt van de puzzel. Denk er dus goed over na hoe je de puzzel in een bepaalde toestand (dus met een aantal stukken ingevuld) gaat representeren. Als je dat bedacht hebt, dan ben je al een heel eind op weg.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan