/* POTM ENTRY: QuackTheDuck */ /* Wolfram Hinderer (Eulfe) */ /* Your email: bords@my-dejanews.com */ /* compile instructions: cc QuackTheDuck.c */ #include #include #include #define TRUE 1 #define FALSE 0 #define MAXGA 6 #define MAXWLEN 9 #define MAXGUESSES 101 FILE *f; int wordlen; char rank[MAXWLEN-2][26][26][27]; char rank1[26]; char rank2[26][27]; char arank[MAXWLEN-2][26][26][27]; char arank1[26]; char arank2[26][27]; int guesses; char s[MAXGUESSES][MAXWLEN]; char h[MAXGUESSES],m[MAXGUESSES],nh[MAXGUESSES],nm[MAXGUESSES],h1[MAXGUESSES],nh1[MAXGUESSES],nm1[MAXGUESSES],charanz[MAXGUESSES][26]; int charinguess[26]; char guess[MAXWLEN],finalguess[MAXWLEN+1],guessarr[MAXGA][MAXWLEN]; int anzpossguesses; int specialmode; char specialword[MAXWLEN]; int bestsum; int maxdepth; char relaxed; void relax(){ int i,j,k,l,m; char d[26],d1[26]; for (i=0;i<26;i++) d1[arank1[i]] = i; for (i=0;i<26;i++) { memcpy(d,arank1,26); k=0; for (j=0;j<26;j++) if (arank2[i][j]>=0) d[d1[arank2[i][j]]]=-1; else{ for (;d[k]<0;k++); arank2[i][j] = d[k++]; } } for (i=0; i=0) d[d1[arank[i][j][k][l]]]=-1; else{ for (;d[m]<0;m++); arank[i][j][k][l] = d[m++]; } } maxdepth=1; relaxed=TRUE; } void saveandexit() { if (specialmode) { int i,j,anzdca,aapg=anzpossguesses; char dca[MAXGA*2],notnew[MAXGA*2],c,nnpos[MAXGA]; for (i=0;i=4) || ((anzpossguesses==3) && (aapg>4))) { finalguess[0] = dca[anzdca]+'A'; for (i=1; i 950){ int i,j=0; if (anzpossguesses==0) if (finalguess[0]==-1) { for (j=0; j=0) guess[0]=rank1[j]; guess[wordlen-1] = guess[0]; for (j=0; j=0) guess[1]=rank2[guess[0]][j]; for (i=2; i=0) {guess[i] = rank[i-2][guess[i-2]][guess[i-1]][j];} for (j=0; j'Z') || (finalguess[j]<'A')) finalguess[j]-=26;} /* if (maxdepth<25) maxdepth++; */ } saveandexit(); } } void doguess() { int i,j; char newguess=TRUE; if ((guesses<1) && (wordlen<=9)) { for (i=0; i<26; i++) if (charinguess[i]>1) return; if (charinguess[guess[wordlen-1]]>0) return; if (charinguess[25]>0) return; } else if ((guesses>0) && (guesses<3) && (h[guesses-1]<2) && (wordlen<=9)) { for (i=0; i<26; i++) if (charinguess[i]>h[guesses-1]+guesses/2+1) return; if (charinguess[guess[wordlen-1]]>h[guesses-1]+guesses/2) return; } for (i=0; i= MAXGA) saveandexit(); } void generateguess2(int n) { int j,k; char r,possible; char ah1[MAXGUESSES],anh1[MAXGUESSES],anm1[MAXGUESSES]; char *ch; ch = rank[n-2][guess[n-2]][guess[n-1]]; if (*ch<0) return; if ((n==3) /*|| (n==wordlen-2)*/) checktime(); memcpy(ah1,h1,guesses); memcpy(anm1,nm1,guesses); memcpy(anh1,nh1,guesses); while (0<= (r =*ch) ) { possible = TRUE; for (j=0; j < guesses; j++) { if (s[j][n] == r) { if ((++h1[j]) > h[j]) {possible = FALSE;break;}} else { if ((++nh1[j]) > nh[j]) {possible = FALSE;break;}} if (charinguess[r]==0) { if ((nm1[j]+=charanz[j][r])>nm[j]) {possible = FALSE;break;}} } if (possible) { int sum=0; guess[n] = r; if (n==wordlen-1){ for (k=0; k < guesses; k++) sum+=nm[k]-nm1[k]; /* if (nm[k] != nm1[k]) {possible = FALSE; break;} if (possible) */ if (sum==0) doguess(); else if (sumh[j]) possible = FALSE;} else { if ((++nh1[j])>nh[j]) possible = FALSE;} if (charinguess[r]==0) { if ((nm1[j]+=charanz[j][r])>nm[j]) possible = FALSE;} } if (possible) { guess[1] = r; charinguess[r]++; generateguess2(2); charinguess[r]--; } memcpy(h1,ah1,guesses); memcpy(nm1,anm1,guesses); memcpy(nh1,anh1,guesses); ch++; checktime(); } } void generateguess() { int i,j; char r,possible; for (i=0; i<=25; charinguess[i++]=0); for (i=0;ih[j]) possible = FALSE;} else { h1[j]=0; nh1[j]=1; if (nh1[j]>nh[j]) possible=FALSE;} if ((nm1[j]=charanz[j][r]) > nm[j]) possible=FALSE; } if (possible) { guess[0] = r; charinguess[r]++; generateguess1(); charinguess[r]--; } } } } void answerguess(char s2[], int h2, int m2) { int i; memcpy(s[guesses],s2,wordlen); h[guesses] = h2; nh[guesses] = wordlen-h2; for (i=0; i<=25; i++) charanz[guesses][i] = 0; for (i=0; i='0') && (c<='9')) { scanf("%s",s1); } else { scanf("%s%d%d",s1,&hinp,&minp); } if (strlen(s1)==1) { wordlen = s1[0]-'0'; f = fopen("TEMP.QuackTheDuck1","w"); for (i=0; i < strlen(datastr); i++) { c4 = datastr[i]; if(c4==10)c4=datastr[++i]; c5 = datastr[++i]; if(c5==10)c5=datastr[++i]; if (c4==31) c4=34; else if (c4==30) c4=92; if (c5==31) c5=34; else if (c5==30) c5=92; n = ((long)c4-(long)32)*(long)(256-32) + (long)c5-32; c3 = (char)(n / (long)(36*36)); n = n % (36*36); c2 = (char)(n / (long)36); c1 = (char)(n % (long)36); if (c1>=26) c1 += '0'-26; else c1 += 'A'; if (c2>=26) c2 += '0'-26; else c2 += 'A'; if (c3>=26) c3 += '0'-26; else c3 += 'A'; fprintf(f,"%c%c%c",c1,c2,c3); } fprintf(f,"0\n"); fflush(f); close(f); f = fopen("TEMP.QuackTheDuck1","r"); for (i=0;i<=25;arank1[i++]=-1); for (i=0;i<=25;i++) for(j=0;j<=26;arank2[i][j++]=-1); for (i=0; i='A') && (c<='Z')) { arank1[l++] = c-'A'; fscanf(f,"%c",&c); } k=-1; i=j=0; while (j==0){ if ((c>='0') && (c<='9')){ emptylines = 0; while ((c>='0') && (c<='9')){ emptylines = 10*emptylines+c-'0'; fscanf(f,"%c",&c);} l = 0; k += emptylines+1; j += k/26; k %= 26; i += j/26; j %= 26; } else{ arank2[k][l++] = c-'A'; fscanf(f,"%c",&c);} } j=0; while (i='0') && (c<='9')){ emptylines = 0; while ((c>='0') && (c<='9')) { emptylines = 10*emptylines+c-'0'; fscanf(f,"%c",&c); } l = 0; k += emptylines+1; j += k/26; k %= 26; i += j/26; j %= 26; } else{ arank[i][j][k][l++] = c-'A'; fscanf(f,"%c",&c); } } close(f); maxdepth = guesses = 0; specialmode = FALSE; relaxed = FALSE; } else { f = fopen("TEMP.QuackTheDuck1","r"); fread(&wordlen,4,1,f); fread(&guesses,4,1,f); fread(arank1,26,1,f); fread(arank2,26*27,1,f); fread(arank,(MAXWLEN-2)*26*26*27,1,f); fread(&maxdepth,sizeof(maxdepth),1,f); fread(s,MAXGUESSES*MAXWLEN,1,f); fread(h,MAXGUESSES,1,f); fread(m,MAXGUESSES,1,f); fread(nh,MAXGUESSES,1,f); fread(nm,MAXGUESSES,1,f); fread(charanz,MAXGUESSES*26,1,f); fread(&specialmode,4,1,f); fread(specialword,wordlen,1,f); fread(&relaxed,sizeof(relaxed),1,f); close(f); for (i=0; i < wordlen; i++) s1[i] -= 'A'; if (guesses<=3) maxdepth=0; else maxdepth--; answerguess(s1,hinp,minp); } memcpy(rank1,arank1,26); memcpy(rank2,arank2,26*27); memcpy(rank,arank,7*26*26*27); for (i=maxdepth+1;i<=25;rank1[i++]=-1); for (i=0;i<=25;i++) for(j=maxdepth+1;j<=25;rank2[i][j++]=-1); for (i=0; i