BSD 1 development
[unix-history] / tests / insan.p
CommitLineData
fde98a2d
BJ
1program insane(input, output);
2label
3 1;
4type
5 alfa = packed array[1..10] of char;
6 face = (front, back, top, bottom, left, right);
7 pair = (one2, three4, five6);
8 color = (red, blue, green, white);
9 blockno = 1..4;
10var
11 nosolutions: Boolean;
12 index, halfindex: integer;
13 pointr: integer;
14 data: array[blockno, face] of alfa;
15 sum: array[blockno, pair, color] of integer;
16 halfsolution: array[blockno, 1..30] of pair;
17
18function word(alf: alfa): color;
19begin
20 if alf = 'red' then
21 word := red else
22 if alf = 'blue' then
23 word := blue else
24 if alf = 'green' then
25 word := green else
26 word := white;
27end;
28
29procedure readin;
30var
31 hue: alfa;
32 ch: char;
33 cube: blockno;
34 position: face;
35
36procedure tone;
37begin
38 case ch of
39 'r': hue := 'red';
40 'w': hue := 'white';
41 'g': hue := 'green';
42 'b': hue := 'blue';
43 end;
44end;
45
46begin
47 for cube := 1 to 4 do
48 begin
49 for position := front to right do
50 begin
51 read(ch);
52 tone;
53 data[cube, position] := hue;
54 end;
55 readln;
56 end;
57end;
58
59procedure sumcolors;
60var
61 cube: blockno;
62 side: face;
63function facepair(aface: face): pair;
64begin
65 case aface of
66 front, back: facepair := one2;
67 top, bottom: facepair := three4;
68 left, right: facepair := five6
69 end;
70end;
71
72procedure initializesum;
73var
74 cube: blockno;
75 side: face;
76 technicolor: color;
77begin
78 for cube := 1 to 4 do
79 for side := front to right do
80 for technicolor := red to white do
81 sum[cube, facepair(side), technicolor] := 0;
82end;
83
84begin
85 initializesum;
86 for cube := 1 to 4 do
87 for side := front to right do
88 sum[cube, facepair(side), word(data[cube,side])] :=
89 sum[cube, facepair(side), word(data[cube,side])] + 1;
90end;
91
92procedure find2222;
93var
94 subtotals: array[red..white] of integer;
95 pair1, pair2, pair3, pair4: pair;
96
97function two222(pair1, pair2, pair3, pair4: pair): Boolean;
98var
99 hue: color;
100begin
101 for hue := red to white do
102 subtotals[hue] :=
103 sum[1, pair1, hue]+
104 sum[2, pair2, hue]+
105 sum[3, pair3, hue]+
106 sum[4, pair4, hue];
107 if (subtotals[red]=2) and
108 (subtotals[blue]=2) and
109 (subtotals[green]=2) and
110 (subtotals[white]=2) then
111 two222 := true else
112 two222 := false;
113end;
114
115procedure listsolution;
116begin
117 halfsolution[1, halfindex] := pair1;
118 halfsolution[2, halfindex] := pair2;
119 halfsolution[3, halfindex] := pair3;
120 halfsolution[4, halfindex] := pair4;
121 halfindex := halfindex + 1;
122end;
123
124begin
125 halfindex := 1;
126 for pair1 := one2 to five6 do
127 for pair2 := one2 to five6 do
128 for pair3 := one2 to five6 do
129 for pair4 := one2 to five6 do
130 if two222(pair1, pair2, pair3, pair4) then
131 listsolution;
132 if halfindex <= 2 then
133 begin
134 nosolutions := true;
135 goto 1;
136 end;
137end;
138
139procedure simultaneous;
140var
141 done: Boolean;
142begin
143 nosolutions := false;
144 pointr := 0;
145 done := false;
146 repeat
147 pointr := pointr + 1;
148 repeat
149 index := succ(pointr);
150 if (halfsolution[1, pointr]<>halfsolution[1,index]) and
151 (halfsolution[2, pointr]<>halfsolution[2,index]) and
152 (halfsolution[3, pointr]<>halfsolution[3,index]) and
153 (halfsolution[4, pointr]<>halfsolution[4,index]) then
154 done := true else
155 index := index + 1;
156 until done or (index = pred(halfindex));
157 until done or (pointr = halfindex);
158 if pointr = halfindex then
159 begin
160 nosolutions := true;
161 goto 1;
162 end;
163end;
164
165procedure rearrange;
166var
167 box: blockno;
168 a, b: pair;
169
170procedure put(a, b: pair);
171var
172 old1, new1, old2, new2: face;
173 save1, save2: alfa;
174
175procedure oldpair(c: pair);
176begin
177 case c of
178 one2:
179 begin
180 old1 := front;
181 old2 := back;
182 end;
183 three4:
184 begin
185 old1 := top;
186 old2 := bottom;
187 end;
188 five6:
189 begin
190 old1 := left;
191 old2 := right;
192 end
193 end;
194end;
195procedure newpair(d: pair);
196begin
197 oldpair(b);
198 new1 := old1;
199 new2 := old2;
200end;
201
202begin
203 newpair(b);
204 oldpair(a);
205 save1 := data[box, new1];
206 data[box, new1] := data[box, old1];
207 data[box, old1] := save1;
208 save2 := data[box, new2];
209 data[box, new2] := data[box, old2];
210 data[box, old2] := save2;
211end;
212
213begin
214 for box := 1 to 4 do
215 begin
216 a := halfsolution[box, pointr];
217 b := halfsolution[box, index];
218 if (a=one2) and (b=five6) then
219 put(five6, three4) else
220 begin
221 if a = three4 then
222 begin
223 if b = one2 then
224 begin
225 put(one2, five6);
226 put(three4, one2);
227 put(five6, three4);
228 end else
229 begin
230 put(three4, one2);
231 put(five6, three4);
232 end
233 end else
234 if b = one2 then
235 begin
236 put(one2, three4);
237 put(five6, one2);
238 end else
239 put(five6, one2);
240 end;
241 end;
242end;
243
244procedure correct;
245var
246 list: array[1..8] of integer;
247 done: Boolean;
248 side: face;
249 counter: integer;
250
251procedure check;
252var
253 delux: array[red..white] of integer;
254 kolor: color;
255 counter: integer;
256begin
257 done := true;
258 for kolor := red to white do
259 for counter := 1 to 4 do
260 delux[kolor] := 0;
261 for counter := 1 to 4 do
262 begin
263 delux[word(data[counter,side])] :=
264 delux[word(data[counter,side])] + 1;
265 if delux[word(data[counter,side])] >= 2 then
266 done := false;
267 end;
268end;
269
270procedure rotate;
271var
272 save: alfa;
273 opposite: face;
274begin
275 if side = back then
276 opposite := front else
277 if side = front then
278 opposite := back else
279 if side = top then
280 opposite := bottom else
281 if side = bottom then
282 opposite := top;
283 save := data[list[counter], side];
284 data[list[counter], side] := data[list[counter], opposite];
285 data[list[counter], opposite] := save;
286end;
287
288begin
289 list[1] := 4;
290 list[2] := 3;
291 list[3] := 4;
292 list[4] := 2;
293 list[5] := 4;
294 list[6] := 3;
295 list[7] := 4;
296 list[8] := 3;
297 for side := back to top do
298 begin
299 counter := 0;
300 check;
301 while not done do
302 begin
303 counter := counter + 1;
304 rotate;
305 check;
306 end;
307 end
308end;
309
310procedure printout;
311var
312 space: integer;
313 cube: integer;
314 side: face;
315begin
316 if nosolutions then
317 writeln('no solutions') else
318 begin
319 writeln('solution to instant insanity');
320 for cube := 1 to 4 do
321 begin
322 write(cube, ' ');
323 for side := front to bottom do
324 write(data[cube, side]);
325 writeln;
326 end;
327 end;
328end;
329
330begin
331 reset(input, 'insan.d');
332 readin;
333 sumcolors;
334 find2222;
335 simultaneous;
336 rearrange;
337 correct;
3381:
339 printout;
340end.
341{
342wbggrb
343wbrgrr
344wbgwrg
345wrgwbr
346}