Commit | Line | Data |
---|---|---|
f9dc10a0 C |
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 |