1 2 static char sccsid[] = " arithmetic.c 4.1 82/10/24 "; 3 4 #include <stdio.h> 5 #include <signal.h> 6 #define MAX 100 7 8 char types[10]; 9 int right[MAX]; 10 int left[MAX]; 11 int rights; 12 int wrongs; 13 long stvec; 14 long etvec; 15 long dtvec; 16 17 main(argc,argv) 18 char *argv[]; 19 { 20 int range, k, dif, l; 21 char line[100]; 22 int ans,pans,i,j,t; 23 char dir,sense; 24 extern delete(); 25 26 signal(SIGINT, delete); 27 28 range = 11; 29 dif = 0; 30 while(argc > 1) { 31 switch(*argv[1]) { 32 case '+': 33 case '-': 34 case 'x': 35 case '/': 36 while(types[dif] = argv[1][dif]) 37 dif++; 38 break; 39 40 default: 41 range = getnum(argv[1]) + 1; 42 } 43 argv++; 44 argc--; 45 } 46 if(range > MAX) { 47 printf("Range is too large.\n"); 48 exit(); 49 } 50 51 if(dif == 0) { 52 types[0] = '+'; 53 types[1] = '-'; 54 dif = 2; 55 } 56 57 for(i = 0; i < range; i++) { 58 left[i] = right[i] = i; 59 } 60 time(&stvec); 61 k = stvec; 62 srand(k); 63 k = 0; 64 l = 0; 65 goto start; 66 67 loop: 68 if(++k%20 == 0) 69 score(); 70 71 start: 72 i = skrand(range); 73 j = skrand(range); 74 if(dif > 1) 75 l = random(dif); 76 77 switch(types[l]) { 78 case '+': 79 default: 80 ans = left[i] + right[j]; 81 printf("%d + %d = ", left[i], right[j]); 82 break; 83 84 case '-': 85 t = left[i] + right[j]; 86 ans = left[i]; 87 printf("%d - %d = ", t, right[j]); 88 break; 89 90 case 'x': 91 ans = left[i] * right[j]; 92 printf("%d x %d = ", left[i], right[j]); 93 break; 94 95 case '/': 96 while(right[j] == 0) 97 j = random(range); 98 t = left[i] * right[j] + random(right[j]); 99 ans = left[i]; 100 printf("%d / %d = ", t, right[j]); 101 break; 102 } 103 104 105 loop1: 106 getline(line); 107 dtvec += etvec - stvec; 108 if(line[0]=='\n') goto loop1; 109 pans = getnum(line); 110 if(pans == ans) { 111 printf("Right!\n"); 112 rights++; 113 goto loop; 114 } 115 else { 116 printf("What?\n"); 117 wrongs++; 118 if(range >= MAX) goto loop1; 119 left[range] = left[i]; 120 right[range++] = right[j]; 121 goto loop1; 122 } 123 } 124 125 getline(s) 126 char *s; 127 { 128 register char *rs; 129 130 rs = s; 131 132 while((*rs = getchar()) == ' '); 133 while(*rs != '\n') 134 if(*rs == 0) 135 exit(); 136 else if(rs >= &s[99]) { 137 while((*rs = getchar()) != '\n') 138 if(*rs == '\0') exit(); 139 } 140 else 141 *++rs = getchar(); 142 while(*--rs == ' ') 143 *rs = '\n'; 144 } 145 146 getnum(s) 147 char *s; 148 { 149 int a; 150 char c; 151 152 a = 0; 153 while((c = *s++) >= '0' && c <= '9') { 154 a = a*10 + c - '0'; 155 } 156 return(a); 157 } 158 159 int arand; 160 161 srand(n) 162 { 163 arand = n&077774 | 01; 164 } 165 166 rand() /*uniform on 0 to 2**13-1*/ 167 { 168 169 arand *= 3125; 170 arand &= 077777; 171 return(arand/4); 172 } 173 174 random(range) 175 { 176 return(hmul(rand(), 8*range)); 177 } 178 179 skrand(range){ 180 int temp; 181 temp = rand() + rand(); 182 if(temp >017777) temp = 040000 - temp; 183 return(hmul(temp,8*range)); 184 } 185 186 /* 'hmul' returns the upper 16 bits of the product, where the operands 187 are assumed to be 16-bit integers. It replaces an old PDP-11 188 assembler language subroutine. -- dks. 189 */ 190 hmul(a,b) { return(a*b >> 16); } 191 score() 192 { 193 time(&etvec); 194 195 printf("\n\nRights %d; Wrongs %d; Score %d%%\n", rights, wrongs, 196 (rights * 100)/(rights + wrongs)); 197 198 if(rights == 0) return; 199 printf("Total time %ld seconds; %.1f seconds per problem\n\n\n", 200 etvec - stvec, 201 (etvec - stvec) / (rights + 0.)); 202 203 sleep(3); 204 time(&dtvec); 205 stvec += dtvec - etvec; 206 return(0); 207 } 208 209 delete() 210 { 211 if(rights + wrongs == 0.) { 212 printf("\n"); 213 exit(); 214 } 215 score(); 216 exit(); 217 } 218 219