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