1: #include <stdio.h>
   2: #include <signal.h>
   3: 
   4: #define NF 10
   5: #define NL 300
   6: #define NC 200
   7: #define SL 100
   8: #define NA 10
   9: 
  10: int tflag;
  11: int xx[NL];
  12: char score[NL];
  13: int rights;
  14: int wrongs;
  15: int guesses;
  16: FILE *input;
  17: int nl = 0;
  18: int na = NA;
  19: int inc;
  20: int ptr  = 0;
  21: int nc = 0;
  22: char line[150];
  23: char response[100];
  24: char *tmp[NF];
  25: int select[NF];
  26: char    *malloc();
  27: 
  28: readline()
  29: {
  30:     char *t;
  31:     register c;
  32: loop:
  33:     for (t=line; c=getc(input), *t=c, c!=EOF; t++) {
  34:         nc++;
  35:         if(*t==' '&&(t==line||t[-1]==' '))
  36:             t--;
  37:         if(*t=='\n') {
  38:             if(t[-1]=='\\')     /*inexact test*/
  39:                 continue;
  40:             while(t>line&&t[-1]==' ')
  41:                 *--t = '\n';
  42:             *++t = 0;
  43:             return(1);
  44:         }
  45:         if(t-line>=NC) {
  46:             printf("Too hard for me\n");
  47:             do {
  48:                 *line = getc(input);
  49:                 if(*line==0377)
  50:                     return(0);
  51:             } while(*line!='\n');
  52:             goto loop;
  53:         }
  54:     }
  55:     return(0);
  56: }
  57: 
  58: char *eu;
  59: char *ev;
  60: cmp(u,v)
  61: char *u, *v;
  62: {
  63:     int x;
  64:     eu = u;
  65:     ev = v;
  66:     x = disj(1);
  67:     if(x!=1)
  68:         return(x);
  69:     return(eat(1,0));
  70: }
  71: 
  72: disj(s)
  73: {
  74:     int t, x;
  75:     char *u;
  76:     u = eu;
  77:     t = 0;
  78:     for(;;) {
  79:         x = string(s);
  80:         if(x>1)
  81:             return(x);
  82:         switch(*ev) {
  83:         case 0:
  84:         case ']':
  85:         case '}':
  86:             return(t|x&s);
  87:         case '|':
  88:             ev++;
  89:             t |= s;
  90:             s = 0;
  91:             continue;
  92:         }
  93:         if(s) eu = u;
  94:         if(string(0)>1)
  95:             return(2);
  96:         switch(*ev) {
  97:         case 0:
  98:         case ']':
  99:             return(0);
 100:         case '}':
 101:             return(1);
 102:         case '|':
 103:             ev++;
 104:             continue;
 105:         default:
 106:             return(2);
 107:         }
 108:     }
 109: }
 110: 
 111: string(s)
 112: {
 113:     int x;
 114:     for(;;) {
 115:         switch(*ev) {
 116:         case 0:
 117:         case '|':
 118:         case ']':
 119:         case '}':
 120:             return(1);
 121:         case '\\':
 122:             ev++;
 123:             if(*ev==0)
 124:                 return(2);
 125:             if(*ev=='\n') {
 126:                 ev++;
 127:                 continue;
 128:             }
 129:         default:
 130:             if(eat(s,*ev)==1)
 131:                 continue;
 132:             return(0);
 133:         case '[':
 134:             ev++;
 135:             x = disj(s);
 136:             if(*ev!=']' || x>1)
 137:                 return(2);
 138:             ev++;
 139:             if(s==0)
 140:                 continue;
 141:             if(x==0)
 142:                 return(0);
 143:             continue;
 144:         case '{':
 145:             ev++;
 146:             x = disj(s);
 147:             if(*ev!='}'||x>1)
 148:                 return(2);
 149:             ev++;
 150:             continue;
 151:         }
 152:     }
 153: }
 154: 
 155: eat(s,c)
 156: char c;
 157: {
 158:     if(*ev!=c)
 159:         return(2);
 160:     if(s==0) {
 161:         ev++;
 162:         return(1);
 163:     }
 164:     if(fold(*eu)!=fold(c))
 165:         return(0);
 166:     eu++;
 167:     ev++;
 168:     return(1);
 169: }
 170: 
 171: fold(c)
 172: char c;
 173: {
 174:     if(c<'A'||c>'Z')
 175:         return(c);
 176:     return(c|040);
 177: }
 178: 
 179: publish(t)
 180: char *t;
 181: {
 182:     ev = t;
 183:     pub1(1);
 184: }
 185: 
 186: pub1(s)
 187: {
 188:     for(;;ev++){
 189:         switch(*ev) {
 190:         case '|':
 191:             s = 0;
 192:             continue;
 193:         case ']':
 194:         case '}':
 195:         case 0:
 196:             return;
 197:         case '[':
 198:         case '{':
 199:             ev++;
 200:             pub1(s);
 201:             continue;
 202:         case '\\':
 203:             if(*++ev=='\n')
 204:                 continue;
 205:         default:
 206:             if(s)
 207:                 putchar(*ev);
 208:         }
 209:     }
 210: }
 211: 
 212: segment(u,w)
 213: char *u, *w[];
 214: {
 215:     char *s;
 216:     int i;
 217:     char *t;
 218:     s = u;
 219:     for(i=0;i<NF;i++) {
 220:         u = s;
 221:         t = w[i];
 222:         while(*s!=':'&&*s!='\n'&&s-u<SL) {
 223:             if(*s=='\\')  {
 224:                 if(s[1] == '\n') {
 225:                     s += 2;
 226:                     continue;
 227:                 }
 228:                 *t++ = *s++;
 229:             }
 230:             *t++ = *s++;
 231:         }
 232: 
 233:         while(*s!=':'&&*s!='\n')
 234:             s++;
 235:         *t = 0;
 236:         if(*s++=='\n') {
 237:             return(i+1);
 238:         }
 239:     }
 240:     printf("Too many facts about one thing\n");
 241:     return(0);
 242: }
 243: 
 244: perm(u,m,v,n,p)
 245: int p[];
 246: char *u[], *v[];
 247: {
 248:     int i, j;
 249:     int x;
 250:     for(i=0;i<m;i++) {
 251:         for(j=0;j<n;j++) {
 252:             x = cmp(u[i],v[j]);
 253:             if(x>1) badinfo();
 254:             if(x==0)
 255:                 continue;
 256:             p[i] = j;
 257:             goto uloop;
 258:         }
 259:         return(0);
 260: uloop:      ;
 261:     }
 262:     return(1);
 263: }
 264: 
 265: find(u,m)
 266: char *u[];
 267: {
 268:     int n;
 269:     while(readline()){
 270:         n = segment(line,tmp);
 271:         if(perm(u,m,tmp+1,n-1,select))
 272:             return(1);
 273:     }
 274:     return(0);
 275: }
 276: 
 277: readindex()
 278: {
 279:     xx[0] = nc = 0;
 280:     while(readline()) {
 281:         xx[++nl] = nc;
 282:         if(nl>=NL) {
 283:             printf("I've forgotten some of it;\n");
 284:             printf("I remember %d items.\n", nl);
 285:             break;
 286:         }
 287:     }
 288: }
 289: 
 290: talloc()
 291: {
 292:     int i;
 293:     for(i=0;i<NF;i++)
 294:         tmp[i] = malloc(SL);
 295: }
 296: 
 297: main(argc,argv)
 298: char *argv[];
 299: {
 300:     register j;
 301:     int i;
 302:     int x;
 303:     int z;
 304:     char *info;
 305:     long tm;
 306:     extern done();
 307:     int count;
 308:     info = "/usr/games/quiz.k/index";
 309:     time(&tm);
 310:     inc = (int)tm&077774|01;
 311: loop:
 312:     if(argc>1&&*argv[1]=='-') {
 313:         switch(argv[1][1]) {
 314:         case 'i':
 315:             if(argc>2)
 316:                 info = argv[2];
 317:             argc -= 2;
 318:             argv += 2;
 319:             goto loop;
 320:         case 't':
 321:             tflag = 1;
 322:             argc--;
 323:             argv++;
 324:             goto loop;
 325:         }
 326:     }
 327:     input = fopen(info,"r");
 328:     if(input==NULL) {
 329:         printf("No info\n");
 330:         exit(0);
 331:     }
 332:     talloc();
 333:     if(argc<=2)
 334:         instruct(info);
 335:     signal(SIGINT, done);
 336:     argv[argc] = 0;
 337:     if(find(&argv[1],argc-1)==0)
 338:         dunno();
 339:     fclose(input);
 340:     input = fopen(tmp[0],"r");
 341:     if(input==NULL)
 342:         dunno();
 343:     readindex();
 344:     if(!tflag || na>nl)
 345:         na = nl;
 346:     stdout->_flag |= _IONBF;
 347:     for(;;) {
 348:         i = next();
 349:         fseek(input,xx[i]+0L,0);
 350:         z = xx[i+1]-xx[i];
 351:         for(j=0;j<z;j++)
 352:             line[j] = getc(input);
 353:         segment(line,tmp);
 354:         if(*tmp[select[0]] == '\0' || *tmp[select[1]] == '\0') {
 355:             score[i] = 1;
 356:             continue;
 357:         }
 358:         publish(tmp[select[0]]);
 359:         printf("\n");
 360:         for(count=0;;count++) {
 361:             if(query(response)==0) {
 362:                 publish(tmp[select[1]]);
 363:                 printf("\n");
 364:                 if(count==0) wrongs++;
 365:                 score[i] = tflag?-1:1;
 366:                 break;
 367:             }
 368:             x = cmp(response,tmp[select[1]]);
 369:             if(x>1) badinfo();
 370:             if(x==1) {
 371:                 printf("Right!\n");
 372:                 if(count==0) rights++;
 373:                 if(++score[i]>=1 && na<nl)
 374:                     na++;
 375:                 break;
 376:             }
 377:             printf("What?\n");
 378:             if(count==0) wrongs++;
 379:             score[i] = tflag?-1:1;
 380:         }
 381:         guesses += count;
 382:     }
 383: }
 384: 
 385: query(r)
 386: char *r;
 387: {
 388:     char *t;
 389:     for(t=r;;t++) {
 390:         if(read(0,t,1)==0)
 391:             done();
 392:         if(*t==' '&&(t==r||t[-1]==' '))
 393:             t--;
 394:         if(*t=='\n') {
 395:             while(t>r&&t[-1]==' ')
 396:                 *--t = '\n';
 397:             break;
 398:         }
 399:     }
 400:     *t = 0;
 401:     return(t-r);
 402: }
 403: 
 404: next()
 405: {
 406:     int flag;
 407:     inc = inc*3125&077777;
 408:     ptr = (inc>>2)%na;
 409:     flag = 0;
 410:     while(score[ptr]>0)
 411:         if(++ptr>=na) {
 412:             ptr = 0;
 413:             if(flag) done();
 414:             flag = 1;
 415:         }
 416:     return(ptr);
 417: }
 418: 
 419: done()
 420: {
 421:     printf("\nRights %d, wrongs %d, ", rights, wrongs);
 422:     if(guesses)
 423:         printf("extra guesses %d, ", guesses);
 424:     printf("score %d%%\n",100*rights/(rights+wrongs));
 425:     exit(0);
 426: }
 427: instruct(info)
 428: char *info;
 429: {
 430:     int i, n;
 431:     printf("Subjects:\n\n");
 432:     while(readline()) {
 433:         printf("-");
 434:         n = segment(line,tmp);
 435:         for(i=1;i<n;i++) {
 436:             printf(" ");
 437:             publish(tmp[i]);
 438:         }
 439:         printf("\n");
 440:     }
 441:     printf("\n");
 442:     input = fopen(info,"r");
 443:     if(input==NULL)
 444:         abort();
 445:     readline();
 446:     segment(line,tmp);
 447:     printf("For example,\n");
 448:     printf("    quiz ");
 449:     publish(tmp[1]);
 450:     printf(" ");
 451:     publish(tmp[2]);
 452:     printf("\nasks you a ");
 453:     publish(tmp[1]);
 454:     printf(" and you answer the ");
 455:     publish(tmp[2]);
 456:     printf("\n    quiz ");
 457:     publish(tmp[2]);
 458:     printf(" ");
 459:     publish(tmp[1]);
 460:     printf("\nworks the other way around\n");
 461:     printf("\nType empty line to get correct answer.\n");
 462:     exit(0);
 463: }
 464: 
 465: badinfo(){
 466:     printf("Bad info %s\n",line);
 467: }
 468: 
 469: dunno()
 470: {
 471:     printf("I don't know about that\n");
 472:     exit(0);
 473: }

Defined functions

badinfo defined in line 465; used 2 times
cmp defined in line 60; used 2 times
disj defined in line 72; used 3 times
done defined in line 419; used 4 times
dunno defined in line 469; used 2 times
eat defined in line 155; used 2 times
find defined in line 265; used 1 times
fold defined in line 171; used 2 times
  • in line 164(2)
instruct defined in line 427; used 1 times
main defined in line 297; never used
next defined in line 404; used 1 times
perm defined in line 244; used 1 times
pub1 defined in line 186; used 2 times
publish defined in line 179; used 9 times
query defined in line 385; used 1 times
readindex defined in line 277; used 1 times
readline defined in line 28; used 4 times
segment defined in line 212; used 4 times
string defined in line 111; used 2 times
talloc defined in line 290; used 1 times

Defined variables

eu defined in line 58; used 5 times
ev defined in line 59; used 26 times
guesses defined in line 15; used 3 times
inc defined in line 19; used 4 times
line defined in line 22; used 13 times
na defined in line 18; used 6 times
nc defined in line 21; used 3 times
nl defined in line 17; used 6 times
ptr defined in line 20; used 5 times
response defined in line 23; used 2 times
rights defined in line 13; used 4 times
score defined in line 12; used 5 times
select defined in line 25; used 6 times
tflag defined in line 10; used 4 times
tmp defined in line 24; used 19 times
wrongs defined in line 14; used 4 times
xx defined in line 11; used 5 times

Defined macros

NA defined in line 8; used 1 times
  • in line 18
NC defined in line 6; used 1 times
  • in line 45
NF defined in line 4; used 4 times
NL defined in line 5; used 3 times
SL defined in line 7; used 2 times
Last modified: 1979-01-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1073
Valid CSS Valid XHTML 1.0 Strict