/* Superhirn 2004 Stefan Reiss, www.reisz.de */ #include using namespace std; #define forint(x,y,z) for(int x = (y);x != (z); ++x) #define min(a,b) ((a)<(b)?(a):(b)) #define F 6 // farben #define S 4 // spalten #define C 1296 // kombinationen = farben**spalten #define D 15 // moegliche ergebnisse = (S+1)*(S+2)/2 bool possible[C]; // noch moegliche kombinationen inline int wert(int g,int v) { return g*(g+1)/2 + v; } int chartosel (const char * s) // wandle text in stellungsnummer { int v=0; forint(k,0,S) { v*=F; v+=s[k]-'a'; } return v; } char * seltochar (int v) // wandle stellungsnummer in text { static char b[S+1]; forint(k,0,S) { b[S-1-k] = 'a'+v%F; v/=F;} return b; } int comp(int s1 , int s2) //vergleich zweier stellungen { static int cc1[F], cc2[F]; forint(k,0,F) cc1[k] = cc2[k] = 0; int g = 0, v = 0 ,p1,p2; // gesamttreffer , volltreffer forint(i,0,S) { p1 = s1%F; s1/=F; ++cc1[p1]; // ermittle die farbe an der position i p2 = s2%F; s2/=F; ++cc2[p2]; // zaehle wie oft jede farbe vorkommt if(p1==p2) ++v; // volltreffer bei uebereinstimmung } { forint(k,0,F) g+=min(cc1[k],cc2[k]); } return wert(g,v); } // welchen verteilungswert gibt die auswahl v int dval(int v) // (summe der quadrate der moeglichkeiten fuer jeden fall) { static int distrib[D]; forint(k,0,D) distrib[k] = 0; forint(i,0,C) if(possible[i]) ++distrib[comp(i,v)]; int val = 0; forint(d,0,D) val+=distrib[d]*distrib[d]; return val; } int bestmove() // zug, der zur besten verteilung fuehrt { int val,bestval=C*C*2 , bestsel=-1; forint(i,0,C) // probiere alle kombinationen { val = dval(i) * 2; // und siehe, welche gibt kleinste verteilung if (possible[i]) --val; // kleiner bonus, wenn zug loesung sein koennte if (val\n"; cout << "-1 fuer ende; 9 fuer neustart\n"; for(int l=1;;++l) { int w, cnt = 0, v = bestmove(); cout << l << ": " << seltochar(v) << " "; cin >> w; if(w==-1) break; if(w==9 || w==11*S) goto start; if(w/10S) cout << "fehler\n"; w = wert(w/10,w%10); forint(i,0,C) if(possible[i]) if(comp(i,v)!=w) possible[i]=0; else ++cnt; if(cnt==1) cout << "geloest!\n"; if(cnt==0) cout << "unmoeglich!\n"; } }