home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / pascal / tests / insan.p < prev    next >
Text File  |  1980-02-17  |  6KB  |  347 lines

  1. program insane(input, output);
  2. label
  3.     1;
  4. type
  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;
  10. var
  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.  
  18. function word(alf: alfa): color;
  19. begin
  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;
  27. end;
  28.  
  29. procedure readin;
  30. var
  31.     hue: alfa;
  32.     ch: char;
  33.     cube: blockno;
  34.     position: face;
  35.  
  36. procedure tone;
  37. begin
  38.     case ch of
  39.     'r': hue := 'red';
  40.     'w': hue := 'white';
  41.     'g': hue := 'green';
  42.     'b': hue := 'blue';
  43.     end;
  44. end;
  45.  
  46. begin
  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;
  57. end;
  58.  
  59. procedure sumcolors;
  60. var
  61.     cube: blockno;
  62.     side: face;
  63. function facepair(aface: face): pair;
  64. begin
  65.     case aface of
  66.     front, back: facepair := one2;
  67.     top, bottom: facepair := three4;
  68.     left, right: facepair := five6
  69.     end;
  70. end;
  71.  
  72. procedure initializesum;
  73. var
  74.     cube: blockno;
  75.     side: face;
  76.     technicolor: color;
  77. begin
  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;
  82. end;
  83.  
  84. begin
  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;
  90. end;
  91.  
  92. procedure find2222;
  93. var
  94.     subtotals: array[red..white] of integer;
  95.     pair1, pair2, pair3, pair4: pair;
  96.  
  97. function two222(pair1, pair2, pair3, pair4: pair): Boolean;
  98. var
  99.     hue: color;
  100. begin
  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;
  113. end;
  114.  
  115. procedure listsolution;
  116. begin
  117.     halfsolution[1, halfindex] := pair1;
  118.     halfsolution[2, halfindex] := pair2;
  119.     halfsolution[3, halfindex] := pair3;
  120.     halfsolution[4, halfindex] := pair4;
  121.     halfindex := halfindex + 1;
  122. end;
  123.  
  124. begin
  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;
  137. end;
  138.  
  139. procedure simultaneous;
  140. var
  141.     done: Boolean;
  142. begin
  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;
  163. end;
  164.  
  165. procedure rearrange;
  166. var
  167.     box: blockno;
  168.     a, b: pair;
  169.  
  170. procedure put(a, b: pair);
  171. var
  172.     old1, new1, old2, new2: face;
  173.     save1, save2: alfa;
  174.  
  175. procedure oldpair(c: pair);
  176. begin
  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;
  194. end;
  195. procedure newpair(d: pair);
  196. begin
  197.     oldpair(b);
  198.     new1 := old1;
  199.     new2 := old2;
  200. end;
  201.  
  202. begin
  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;
  211. end;
  212.  
  213. begin
  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;
  242. end;
  243.  
  244. procedure correct;
  245. var
  246.     list: array[1..8] of integer;
  247.     done: Boolean;
  248.     side: face;
  249.     counter: integer;
  250.  
  251. procedure check;
  252. var
  253.     delux: array[red..white] of integer;
  254.     kolor: color;
  255.     counter: integer;
  256. begin
  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;
  268. end;
  269.  
  270. procedure rotate;
  271. var
  272.     save: alfa;
  273.     opposite: face;
  274. begin
  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;
  286. end;
  287.  
  288. begin
  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
  308. end;
  309.  
  310. procedure printout;
  311. var
  312.     space: integer;
  313.     cube: integer;
  314.     side: face;
  315. begin
  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;
  328. end;
  329.  
  330. begin
  331.     reset(input, 'insan.d');
  332.     readin;
  333.     sumcolors;
  334.     find2222;
  335.     simultaneous;
  336.     rearrange;
  337.     correct;
  338. 1:
  339.     printout;
  340. end.
  341. {
  342. wbggrb
  343. wbrgrr
  344. wbgwrg
  345. wrgwbr
  346. }
  347.