Bell 32V development
[unix-history] / usr / src / cmd / arithmetic.c
CommitLineData
3b600ead
TL
1#include <stdio.h>
2#include <signal.h>
3#define MAX 100
4
5char types[10];
6int right[MAX];
7int left[MAX];
8int rights;
9int wrongs;
10long stvec;
11long etvec;
12long dtvec;
13
14main(argc,argv)
15char *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
64loop:
65 if(++k%20 == 0)
66 score();
67
68start:
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
102loop1:
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
122getline(s)
123char *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
143getnum(s)
144char *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
156int arand;
157
158srand(n)
159{
160 arand = n&077774 | 01;
161}
162
163rand() /*uniform on 0 to 2**13-1*/
164{
165
166 arand *= 3125;
167 arand &= 077777;
168 return(arand/4);
169}
170
171random(range)
172{
173 return(hmul(rand(), 8*range));
174}
175
176skrand(range){
177int 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*/
187hmul(a,b) { return(a*b >> 16); }
188score()
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
206delete()
207{
208 if(rights + wrongs == 0.) {
209 printf("\n");
210 exit();
211 }
212 score();
213 exit();
214}
215