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