home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / dev / obero / oberon / demos / hennessy.mod (.txt) < prev    next >
Encoding:
Oberon Text  |  1995-04-06  |  20.1 KB  |  891 lines

  1. Syntax10.Scn.Fnt
  2. MODULE Hennessy;
  3. (*  This is a suite of benchmarks that are relatively short, both in program
  4.     size and execution time.  It requires no input, and prints the execution
  5.     time for each program, using the system- dependent routine Getclock,
  6.     below, to find out the current CPU time.  It does a rudimentary check to
  7.     make sure each program gets the right output.  These programs were
  8.     gathered by John Hennessy and modified by Peter Nye.
  9.     Oberon: J.Templ 26.2.90 *)
  10. IMPORT
  11.     Oberon, Texts, S := SYSTEM;
  12. CONST
  13.     bubblebase = 1.61;
  14.     dnfbase = 3.5;
  15.     permbase = 1.75;
  16.     queensbase = 1.83;
  17.     towersbase = 2.39;
  18.     quickbase = 1.92;
  19.     intmmbase = 1.46;
  20.     treebase =  2.5;
  21.     mmbase = 0.0 (* 0.73 *);
  22.     fpmmbase = 2.92;
  23.     puzzlebase = 0.5;
  24.     fftbase = 0.0 (* 1.11 *);
  25.     fpfftbase = 4.44;
  26.     (* Towers *)
  27.     maxcells = 18;
  28.     stackrange = (*0..*) 3;
  29.     (* Intmm, Mm *)
  30.     rowsize = 40;
  31.     (* Puzzle *)
  32.     size = 511;
  33.     classmax = 3;
  34.     typemax = 12;
  35.     d = 8;
  36.     (* Bubble, Quick *)
  37.     sortelements = 5000;
  38.     srtelements = 500;
  39.     (* fft *)
  40.     fftsize = 256;
  41.     fftsize2 = 129;
  42.     (* Perm *)
  43.     permrange = (*0 ..*)10;
  44.     (* Towers *)
  45.     (* tree *)
  46.     node = POINTER TO nodeDesc;
  47.     nodeDesc = RECORD
  48.         left, right: node;
  49.         val: LONGINT;
  50.     END;
  51.     (* Towers
  52.     discsizrange = 1..maxcells;
  53.     cellcursor = 0..maxcells; *)
  54.     element = RECORD
  55.         discsize: LONGINT;
  56.         next: LONGINT;
  57.     END ;
  58. (*    emsgtype = packed array[1..15] of char;
  59.     (* Intmm, Mm *) (*
  60.     index = 1 .. rowsize; *)
  61.     intmatrix = ARRAY rowsize+1,rowsize+1 OF LONGINT;
  62.     realmatrix = ARRAY rowsize+1,rowsize+1 OF REAL;
  63.     (* Puzzle *) (*
  64.     piececlass = 0..classmax;
  65.     piecetype = 0..typemax;
  66.     position = 0..size;
  67.     (* Bubble, Quick *) (*
  68.     listsize = 0..sortelements;
  69.     sortarray = array [listsize] of integer;
  70.     (* FFT *)
  71.     complex = RECORD
  72.         rp, ip: REAL
  73.     END;
  74.     carray = ARRAY fftsize+1 OF complex ;
  75.     c2array = ARRAY fftsize2+1 OF complex ;
  76.     Proc = PROCEDURE;
  77.     fixed,floated: REAL;
  78.     (* global *)
  79.     seed: LONGINT;
  80.     (* Perm *)
  81.     permarray: ARRAY permrange+1 OF LONGINT;
  82.     pctr: LONGINT;
  83.     (* tree *)
  84.     tree: node;
  85.     (* Towers *)
  86.     stack: ARRAY stackrange+1 OF LONGINT;
  87.     cellspace: ARRAY maxcells+1 OF element;
  88.     freelist: LONGINT;
  89.     movesdone: LONGINT;
  90.     (* Intmm, Mm *)
  91.     ima, imb, imr: intmatrix;
  92.     rma, rmb, rmr: realmatrix;
  93.     (* Puzzle *)
  94.     piececount: ARRAY classmax+1 OF LONGINT;
  95.     class, piecemax: ARRAY typemax+1 OF LONGINT;
  96.     puzzl: ARRAY size+1 OF BOOLEAN;
  97.     p: ARRAY typemax+1, size+1 OF BOOLEAN;
  98.     kount: LONGINT;
  99.     (* Bubble, Quick *)
  100.     sortlist: ARRAY sortelements+1 OF LONGINT;
  101.     biggest, littlest,
  102.     top: LONGINT;
  103.     (* FFT *)
  104.     z, w: carray;
  105.     e: c2array;
  106.     zr, zi: REAL;
  107.       W: Texts.Writer;
  108. (* global procedures *)
  109. PROCEDURE Str*(s: ARRAY OF CHAR);
  110.     VAR i: INTEGER;
  111. BEGIN
  112.     i:=0;
  113.     WHILE s[i] # 0X DO
  114.         IF s[i]="$" THEN Texts.WriteLn(W) ELSE Texts.Write(W, s[i]) END;
  115.         INC(i)
  116.     END;
  117.     Texts.Append(Oberon.Log, W.buf)
  118. END Str;
  119. PROCEDURE Getclock (): LONGINT;
  120. BEGIN
  121.     RETURN Oberon.Time()
  122. END Getclock;
  123. PROCEDURE Initrand ();
  124. BEGIN seed := 74755
  125. END Initrand;
  126. PROCEDURE Rand (): LONGINT;
  127. BEGIN
  128.     seed := (seed * 1309 + 13849) MOD 65535;
  129.     RETURN (seed);
  130. END Rand;
  131.     (* Permutation program, heavily recursive, written by Denny Brown. *)
  132.     PROCEDURE Swap (VAR a,b: LONGINT);
  133.         VAR t: LONGINT;
  134.     BEGIN t := a;  a := b;  b := t;
  135.     END Swap;
  136.     PROCEDURE Initialize ();
  137.         VAR i: LONGINT;
  138.     BEGIN i := 1;
  139.         WHILE i <= 7 DO
  140.             permarray[i] := i-1;
  141.             INC(i)
  142.         END
  143.     END Initialize;
  144.     PROCEDURE Permute (n: LONGINT);
  145.         VAR k: LONGINT;
  146.     BEGIN
  147.         pctr := pctr + 1;
  148.         IF ( n#1 ) THEN
  149.             Permute(n-1);
  150.             k := n-1;
  151.             WHILE k >= 1 DO
  152.                 Swap(permarray[n], permarray[k]);
  153.                 Permute(n-1);
  154.                 Swap(permarray[n], permarray[k]);
  155.                 DEC(k)
  156.             END
  157.        END
  158.     END Permute;
  159. PROCEDURE *Perm ();
  160.     VAR i: LONGINT;
  161. BEGIN
  162.     pctr := 0; i := 1;
  163.     WHILE i <= 5 DO
  164.         Initialize();
  165.         Permute(7);
  166.         INC(i)
  167.     END ;
  168.     IF ( pctr # 43300 ) THEN Str(" Error in Perm.$") END
  169. END Perm;
  170.     (*  Program to Solve the Towers of Hanoi *)
  171.     PROCEDURE Makenull (s: LONGINT);
  172.     BEGIN stack[s] := 0
  173.     END Makenull;
  174.     PROCEDURE Getelement (): LONGINT;
  175.         VAR temp: LONGINT;
  176.     BEGIN
  177.         IF ( freelist>0 ) THEN
  178.             temp := freelist;
  179.             freelist := cellspace[freelist].next;
  180.         ELSE
  181.             Str("out of space   $")
  182.         END ;
  183.         RETURN (temp);
  184.     END Getelement;
  185.     PROCEDURE Push(i,s: LONGINT);
  186.         VAR localel: LONGINT; errorfound: BOOLEAN;
  187.     BEGIN
  188.         errorfound := FALSE;
  189.         IF ( stack[s] > 0 ) THEN
  190.             IF ( cellspace[stack[s]].discsize<=i ) THEN
  191.                 errorfound := TRUE;
  192.                 Str("disc size error$")
  193.             END 
  194.         END ;
  195.         IF ( ~ errorfound ) THEN
  196.             localel := Getelement();
  197.             cellspace[localel].next := stack[s];
  198.             stack[s] := localel;
  199.             cellspace[localel].discsize := i
  200.         END
  201.     END Push;
  202.     PROCEDURE Init (s,n: LONGINT);
  203.         VAR discctr: LONGINT;
  204.     BEGIN
  205.         Makenull(s); discctr := n;
  206.         WHILE discctr >= 1 DO
  207.             Push(discctr,s);
  208.             DEC(discctr)
  209.         END
  210.     END Init;
  211.     PROCEDURE Pop (s: LONGINT): LONGINT;
  212.         VAR temp, temp1: LONGINT;
  213.     BEGIN
  214.         IF ( stack[s] > 0 ) THEN
  215.             temp1 := cellspace[stack[s]].discsize;
  216.             temp := cellspace[stack[s]].next;
  217.             cellspace[stack[s]].next := freelist;
  218.             freelist := stack[s];
  219.             stack[s] := temp;
  220.             RETURN (temp1)
  221.         ELSE
  222.             Str("nothing to pop $")
  223.         END
  224.     END Pop;
  225.     PROCEDURE Move (s1,s2: LONGINT);
  226.     BEGIN
  227.         Push(Pop(s1),s2);
  228.         movesdone := movesdone+1;
  229.     END Move;
  230.     PROCEDURE tower(i,j,k: LONGINT);
  231.         VAR other: LONGINT;
  232.     BEGIN
  233.         IF ( k=1 ) THEN
  234.             Move(i,j);
  235.         ELSE
  236.             other := 6-i-j;
  237.             tower(i,other,k-1);
  238.             Move(i,j);
  239.             tower(other,j,k-1)
  240.         END
  241.     END tower;
  242. PROCEDURE *Towers ();
  243.     VAR i: LONGINT;
  244. BEGIN i := 1;
  245.     WHILE i <= maxcells DO cellspace[i].next := i-1; INC(i) END ;
  246.     freelist := maxcells;
  247.     Init(1,14);
  248.     Makenull(2);
  249.     Makenull(3);
  250.     movesdone := 0;
  251.     tower(1,2,14);
  252.     IF ( movesdone # 16383 ) THEN Str(" Error in Towers.$") END
  253. END Towers;
  254.     (* The eight queens problem, solved 50 times. *)
  255.   type
  256.       doubleboard =   2..16;
  257.       doublenorm  =   -7..7;
  258.       boardrange  =   1..8;
  259.       aarray      =   array [boardrange] of boolean;
  260.       barray      =   array [doubleboard] of boolean;
  261.       carray      =   array [doublenorm] of boolean;
  262.       xarray      =   array [boardrange] of boardrange;
  263.     PROCEDURE Try(i: LONGINT; VAR q: BOOLEAN; VAR a, b, c: ARRAY OF BOOLEAN; VAR x: ARRAY OF LONGINT);
  264.         VAR j: LONGINT;
  265.     BEGIN
  266.         j := 0;
  267.         q := FALSE;
  268.         WHILE (~q) & (j # 8) DO
  269.             j := j + 1;
  270.             q := FALSE;
  271.             IF b[j] & a[i+j] & c[i-j+7] THEN
  272.                 x[i] := j;
  273.                 b[j] := FALSE;
  274.                 a[i+j] := FALSE;
  275.                 c[i-j+7] := FALSE;
  276.                 IF i < 8 THEN
  277.                     Try(i+1,q,a,b,c,x);
  278.                     IF ~q THEN
  279.                         b[j] := TRUE;
  280.                         a[i+j] := TRUE;
  281.                         c[i-j+7] := TRUE
  282.                     END
  283.                 ELSE q := TRUE
  284.                 END
  285.             END
  286.         END
  287.     END Try;
  288.     PROCEDURE Doit ();
  289.         VAR i: LONGINT; q: BOOLEAN;
  290.             a: ARRAY 9 OF BOOLEAN;
  291.             b: ARRAY 17 OF BOOLEAN;
  292.             c: ARRAY 15 OF BOOLEAN;
  293.             x: ARRAY 9 OF LONGINT;
  294.     BEGIN
  295.         i := 0 - 7;
  296.         WHILE i <= 16 DO
  297.             IF (i >= 1) & (i <= 8) THEN a[i] := TRUE END ;
  298.             IF i >= 2 THEN b[i] := TRUE END ;
  299.             IF i <= 7 THEN c[i+7] := TRUE END ;
  300.             i := i + 1;
  301.         END ;
  302.         Try(1, q, b, a, c, x);
  303.         IF ( ~ q ) THEN Str(" Error in Queens.$") END
  304.     END Doit;
  305. PROCEDURE *Queens ();
  306.     VAR i: LONGINT;
  307. BEGIN i := 1;
  308.     WHILE i <= 50 DO Doit(); INC(i) END
  309. END Queens;
  310.     (* Multiplies two integer matrices. *)
  311.     PROCEDURE Initmatrix (VAR m: intmatrix);
  312.         VAR temp, i, j: LONGINT;
  313.     BEGIN i := 1;
  314.         WHILE i <= rowsize DO
  315.             j := 1;
  316.             WHILE j <= rowsize DO
  317.                 temp := Rand();
  318.                 m[i][j] := temp - (temp DIV 120)*120 - 60;
  319.                 INC(j)
  320.             END ;
  321.             INC(i)
  322.         END
  323.     END Initmatrix;
  324.     PROCEDURE Innerproduct(VAR result: LONGINT; VAR a,b: intmatrix; row,column: LONGINT);
  325.         VAR i: LONGINT;
  326.   (* computes the inner product of A[row,*] and B[*,column] *)
  327.     BEGIN
  328.         result := 0; i := 1;
  329.         WHILE i <= rowsize DO result := result+a[row][i]*b[i][column]; INC(i) END
  330.     END Innerproduct;
  331. PROCEDURE *Intmm ();
  332.     VAR i, j: LONGINT;
  333. BEGIN
  334.     Initrand();
  335.     Initmatrix (ima);
  336.     Initmatrix (imb);
  337.     i := 1;
  338.     WHILE i <= rowsize DO j := 1;
  339.         WHILE j <= rowsize DO Innerproduct(imr[i][j],ima,imb,i,j); INC(j) END ;
  340.         INC(i)
  341. END Intmm;
  342.     (* Multiplies two real matrices. *)
  343.     PROCEDURE rInitmatrix (VAR m: realmatrix);
  344.         VAR temp, i, j: LONGINT;
  345.     BEGIN i := 1;
  346.         WHILE i <= rowsize DO j := 1;
  347.             WHILE j <= rowsize DO
  348.                 temp := Rand();
  349.                 m[i][j] := (temp - (temp DIV 120)*120 - 60) DIV 3;
  350.                 INC(j)
  351.             END ;
  352.             INC(i)
  353.         END
  354.     END rInitmatrix;
  355.     PROCEDURE rInnerproduct(VAR result: REAL; VAR a,b: realmatrix; row,column: LONGINT);
  356.     (* computes the inner product of A[row,*] and B[*,column] *)
  357.         VAR i: LONGINT;
  358.     BEGIN
  359.         result := 0.0; i := 1;
  360.         WHILE i<=rowsize DO result := result+a[row][i]*b[i][column]; INC(i) END
  361.     END rInnerproduct;
  362. PROCEDURE *Mm ();
  363.     VAR i, j: LONGINT;
  364. BEGIN
  365.     Initrand();
  366.     rInitmatrix (rma);
  367.     rInitmatrix (rmb);
  368.     i := 1;
  369.     WHILE i <= rowsize DO j := 1;
  370.         WHILE j <= rowsize DO rInnerproduct(rmr[i][j],rma,rmb,i,j); INC(j) END ;
  371.         INC(i)
  372. END Mm;
  373.     (* A compute-bound program from Forest Baskett. *)
  374.     PROCEDURE Fit (i, j: LONGINT): BOOLEAN;
  375.         VAR k: LONGINT;
  376.     BEGIN k := 0;
  377.         WHILE k <= piecemax[i] DO
  378.             IF ( p[i][k] ) THEN IF ( puzzl[j+k] ) THEN RETURN FALSE END END;
  379.             INC(k)
  380.         END;
  381.         RETURN TRUE
  382.     END Fit;
  383.     PROCEDURE Place (i, j: LONGINT): LONGINT;
  384.         VAR k: LONGINT;
  385.     BEGIN k := 0;
  386.         WHILE k <= piecemax[i] DO
  387.             IF ( p[i][k] ) THEN puzzl[j+k] := TRUE END;
  388.             INC(k)
  389.         END;
  390.         piececount[class[i]] := piececount[class[i]] - 1;
  391.         k := j;
  392.         WHILE k <= size DO
  393.             IF ( ~ puzzl[k] ) THEN RETURN (k) END;
  394.             INC(k)
  395.         END ;
  396.         RETURN (0);
  397.     END Place;
  398.     PROCEDURE Remove (i, j: LONGINT);
  399.         VAR k: LONGINT;
  400.     BEGIN k := 0;
  401.         WHILE k <= piecemax[i] DO
  402.             IF ( p[i][k] ) THEN puzzl[j+k] := FALSE END;
  403.             INC(k)
  404.         END;
  405.         piececount[class[i]] := piececount[class[i]] + 1
  406.     END Remove;
  407.     PROCEDURE Trial (j: LONGINT): BOOLEAN;
  408.         VAR i, k: LONGINT;
  409.     BEGIN i := 0;
  410.         kount := kount + 1;
  411.         WHILE i <= typemax DO
  412.             IF ( piececount[class[i]] # 0 ) THEN
  413.                 IF ( Fit (i, j) ) THEN
  414.                     k := Place (i, j);
  415.                     IF Trial(k) OR (k = 0) THEN RETURN (TRUE)
  416.                     ELSE Remove (i, j)
  417.                     END;
  418.                 END
  419.             END;
  420.             INC(i)
  421.         END;
  422.         RETURN (FALSE)
  423.     END Trial;
  424. PROCEDURE* Puzzle ();
  425.     VAR i, j, k, m: LONGINT;
  426. BEGIN
  427.     m := 0; WHILE m <= size DO puzzl[m] := TRUE; INC(m) END ;
  428.     i := 1;
  429.     WHILE i <= 5 DO j := 1;
  430.         WHILE j <= 5 DO k := 1;
  431.             WHILE k <= 5 DO
  432.                 puzzl[i+d*(j+d*k)] := FALSE; INC(k)
  433.             END;
  434.             INC(j)
  435.         END;
  436.         INC(i)
  437.     END;
  438.     i := 0; 
  439.     WHILE i <= typemax DO m := 0;
  440.         WHILE m<= size DO
  441.             p[i][m] := FALSE; INC(m)
  442.         END;
  443.         INC(i)
  444.     END;
  445.     i := 0;
  446.     WHILE i <= 3 DO j := 0;
  447.         WHILE j <= 1 DO k := 0;
  448.             WHILE k <= 0 DO
  449.                 p[0][i+d*(j+d*k)] := TRUE; INC(k)
  450.             END;
  451.             INC(j)
  452.         END;
  453.         INC(i)
  454.     END;
  455.     class[0] := 0;
  456.     piecemax[0] := 3+d*1+d*d*0;
  457.     i := 0;
  458.     WHILE i <= 1 DO j := 0;
  459.         WHILE j <= 0 DO k := 0;
  460.             WHILE k <= 3 DO
  461.                 p[1][i+d*(j+d*k)] := TRUE; INC(k)
  462.             END;
  463.             INC(j)
  464.         END;
  465.         INC(i)
  466.     END;
  467.     class[1] := 0;
  468.     piecemax[1] := 1+d*0+d*d*3;
  469.     i := 0;
  470.     WHILE i <= 0 DO j := 0;
  471.         WHILE j <= 3 DO k := 0;
  472.             WHILE k <= 1 DO
  473.                 p[2][i+d*(j+d*k)] := TRUE; INC(k)
  474.             END;
  475.             INC(j)
  476.         END;
  477.         INC(i)
  478.     END;
  479.     class[2] := 0;
  480.     piecemax[2] := 0+d*3+d*d*1;
  481.     i := 0;
  482.     WHILE i <= 1 DO j := 0;
  483.         WHILE j <= 3 DO k := 0;
  484.             WHILE k <= 0 DO
  485.                 p[3][i+d*(j+d*k)] := TRUE; INC(k)
  486.             END;
  487.             INC(j)
  488.         END;
  489.         INC(i)
  490.     END;
  491.     class[3] := 0;
  492.     piecemax[3] := 1+d*3+d*d*0;
  493.     i := 0;
  494.     WHILE i <= 3 DO j := 0;
  495.         WHILE j <= 0 DO k := 0;
  496.             WHILE k <= 1 DO
  497.                 p[4][i+d*(j+d*k)] := TRUE; INC(k)
  498.             END;
  499.             INC(j)
  500.         END;
  501.         INC(i)
  502.     END;
  503.     class[4] := 0;
  504.     piecemax[4] := 3+d*0+d*d*1;
  505.     i := 0;
  506.     WHILE i <= 0 DO j := 0;
  507.         WHILE j <= 1 DO k := 0;
  508.             WHILE k <= 3 DO
  509.                 p[5][i+d*(j+d*k)] := TRUE; INC(k)
  510.             END;
  511.             INC(j)
  512.         END;
  513.         INC(i)
  514.     END;
  515.     class[5] := 0;
  516.     piecemax[5] := 0+d*1+d*d*3;
  517.     i := 0;
  518.     WHILE i <= 2 DO j := 0;
  519.         WHILE j <= 0 DO k := 0;
  520.             WHILE k <= 0 DO
  521.                 p[6][i+d*(j+d*k)] := TRUE; INC(k)
  522.             END;
  523.             INC(j)
  524.         END;
  525.         INC(i)
  526.     END;
  527.     class[6] := 1;
  528.     piecemax[6] := 2+d*0+d*d*0;
  529.     i := 0;
  530.     WHILE i <= 0 DO j := 0;
  531.         WHILE j <= 2 DO k := 0;
  532.             WHILE k <= 0 DO
  533.                 p[7][i+d*(j+d*k)] := TRUE; INC(k)
  534.             END;
  535.             INC(j)
  536.         END;
  537.         INC(i)
  538.     END;
  539.     class[7] := 1;
  540.     piecemax[7] := 0+d*2+d*d*0;
  541.     i := 0;
  542.     WHILE i <= 0 DO j := 0;
  543.         WHILE j <= 0 DO k := 0;
  544.             WHILE k <= 2 DO
  545.                 p[8][i+d*(j+d*k)] := TRUE; INC(k)
  546.             END;
  547.             INC(j)
  548.         END;
  549.         INC(i)
  550.     END;
  551.     class[8] := 1;
  552.     piecemax[8] := 0+d*0+d*d*2;
  553.     i := 0;
  554.     WHILE i <= 1 DO j := 0;
  555.         WHILE j <= 1 DO k := 0;
  556.             WHILE k <= 0 DO
  557.                 p[9][i+d*(j+d*k)] := TRUE; INC(k)
  558.             END;
  559.             INC(j)
  560.         END;
  561.         INC(i)
  562.     END;
  563.     class[9] := 2;
  564.     piecemax[9] := 1+d*1+d*d*0;
  565.     i := 0;
  566.     WHILE i <= 1 DO j := 0;
  567.         WHILE j <= 0 DO k := 0;
  568.             WHILE k <= 1 DO
  569.                 p[10][i+d*(j+d*k)] := TRUE; INC(k)
  570.             END;
  571.             INC(j)
  572.         END;
  573.         INC(i)
  574.     END;
  575.     class[10] := 2;
  576.     piecemax[10] := 1+d*0+d*d*1;
  577.     i := 0;
  578.     WHILE i <= 0 DO j := 0;
  579.         WHILE j <= 1 DO k := 0;
  580.             WHILE k <= 1 DO
  581.                 p[11][i+d*(j+d*k)] := TRUE; INC(k)
  582.             END;
  583.             INC(j)
  584.         END;
  585.         INC(i)
  586.     END;
  587.     class[11] := 2;
  588.     piecemax[11] := 0+d*1+d*d*1;
  589.     i := 0;
  590.     WHILE i <= 1 DO j := 0;
  591.         WHILE j <= 1 DO k := 0;
  592.             WHILE k <= 1 DO
  593.                 p[12][i+d*(j+d*k)] := TRUE; INC(k)
  594.             END;
  595.             INC(j)
  596.         END;
  597.         INC(i)
  598.     END;
  599.     class[12] := 3;
  600.     piecemax[12] := 1+d*1+d*d*1;
  601.     piececount[0] := 13;
  602.     piececount[1] := 3;
  603.     piececount[2] := 1;
  604.     piececount[3] := 1;
  605.     m := 1+d*(1+d*1);
  606.     kount := 0;
  607.     IF Fit(0, m) THEN n := Place(0, m)
  608.     ELSE Str("Error1 in Puzzle$")
  609.     END;
  610.     IF ~ Trial(n) THEN Str("Error2 in Puzzle.$")
  611.     ELSIF kount # 2005 THEN Str("Error3 in Puzzle.$")
  612. END Puzzle;
  613.    (* Sorts an array using quicksort *)
  614.     PROCEDURE Initarr();
  615.         VAR i, temp: LONGINT;
  616.     BEGIN
  617.         Initrand();
  618.         biggest := 0; littlest := 0; i := 1;
  619.         WHILE i <= sortelements DO
  620.             temp := Rand();
  621.             sortlist[i] := temp - (temp DIV 100000)*100000 - 50000;
  622.             IF sortlist[i] > biggest THEN biggest := sortlist[i]
  623.             ELSIF sortlist[i] < littlest THEN littlest := sortlist[i]
  624.             END ;
  625.             INC(i)
  626.         END
  627.     END Initarr;
  628.     PROCEDURE Quicksort(VAR a: ARRAY OF LONGINT; l,r: LONGINT);
  629.   (* quicksort the array A from start to finish *)
  630.         VAR i,j,x,w: LONGINT;
  631.     BEGIN
  632.         i:=l; j:=r;
  633.         x:=a[(l+r) DIV 2];
  634.         REPEAT
  635.             WHILE a[i]<x DO i := i+1 END;
  636.             WHILE x<a[j] DO j := j-1 END;
  637.             IF i<=j THEN
  638.                 w := a[i];
  639.                 a[i] := a[j];
  640.                 a[j] := w;
  641.                 i := i+1;    j := j-1
  642.             END ;
  643.         UNTIL i > j;
  644.         IF l<j THEN Quicksort(a,l,j) END;
  645.         IF i<r THEN Quicksort(a,i,r) END
  646.     END Quicksort;
  647. PROCEDURE* Quick ();
  648. BEGIN
  649.     Initarr();
  650.     Quicksort(sortlist,1,sortelements);
  651.     IF (sortlist[1] # littlest) OR (sortlist[sortelements] # biggest) THEN  Str( " Error in Quick.$") END ;
  652. END Quick;
  653.     (* Sorts an array using bubblesort *)
  654.     PROCEDURE bInitarr();
  655.         VAR i, temp: LONGINT;
  656.     BEGIN
  657.         Initrand();
  658.         biggest := 0; littlest := 0; i := 1;
  659.         WHILE i <= srtelements DO
  660.             temp := Rand();
  661.             sortlist[i] := temp - (temp DIV 100000)*100000 - 50000;
  662.             IF sortlist[i] > biggest THEN biggest := sortlist[i]
  663.             ELSIF sortlist[i] < littlest THEN littlest := sortlist[i]
  664.             END ;
  665.             INC(i)
  666.         END
  667.     END bInitarr;
  668. PROCEDURE* Bubble();
  669.     VAR i, j: LONGINT;
  670. BEGIN
  671.     bInitarr();
  672.     top:=srtelements;
  673.     WHILE top>1 DO
  674.         i:=1;
  675.         WHILE i<top DO
  676.             IF sortlist[i] > sortlist[i+1] THEN
  677.                 j := sortlist[i];
  678.                 sortlist[i] := sortlist[i+1];
  679.                 sortlist[i+1] := j;
  680.             END ;
  681.             i:=i+1;
  682.         END;
  683.         top:=top-1;
  684.     END;
  685.     IF (sortlist[1] # littlest) OR (sortlist[srtelements] # biggest) THEN Str("Error3 in Bubble.$") END ;
  686. END Bubble;
  687.     (* Sorts an array using treesort *)
  688.     PROCEDURE tInitarr();
  689.         VAR i, temp: LONGINT;
  690.     BEGIN
  691.         Initrand();
  692.         biggest := 0; littlest := 0; i := 1;
  693.         WHILE i <= sortelements DO
  694.             temp := Rand();
  695.             sortlist[i] := temp - (temp DIV 100000)*100000 - 50000;
  696.             IF sortlist[i] > biggest THEN biggest := sortlist[i]
  697.             ELSIF sortlist[i] < littlest THEN littlest := sortlist[i]
  698.             END ;
  699.             INC(i)
  700.         END
  701.     END tInitarr;
  702.     PROCEDURE CreateNode (VAR t: node; n: LONGINT);
  703.     BEGIN
  704.         NEW(t);
  705.         t.left := NIL; t.right := NIL;
  706.         t.val := n
  707.     END CreateNode;
  708.     PROCEDURE Insert(n: LONGINT; t: node);
  709.     (* insert n into tree *)
  710.     BEGIN
  711.         IF n > t.val THEN
  712.             IF t.left = NIL THEN CreateNode(t.left,n)
  713.             ELSE Insert(n,t.left)
  714.             END
  715.         ELSIF n < t.val THEN
  716.             IF t.right = NIL THEN CreateNode(t.right,n)
  717.             ELSE Insert(n,t.right)
  718.             END
  719.         END
  720.     END Insert;
  721.     PROCEDURE Checktree(p: node): BOOLEAN;
  722.     (* check by inorder traversal *)
  723.         VAR result: BOOLEAN;
  724.     BEGIN
  725.         result := TRUE;
  726.         IF p.left # NIL THEN
  727.             IF p.left.val <= p.val THEN result := FALSE;
  728.             ELSE result := Checktree(p.left) & result
  729.             END
  730.         END ;
  731.         IF  p.right # NIL THEN
  732.             IF p.right.val >= p.val THEN result := FALSE;
  733.             ELSE result := Checktree(p.right) & result
  734.             END
  735.         END;
  736.         RETURN result
  737.     END Checktree;
  738. PROCEDURE* Trees();
  739.     VAR i: LONGINT;
  740. BEGIN
  741.     tInitarr();
  742.     NEW(tree);
  743.     tree.left := NIL; tree.right:=NIL; tree.val:=sortlist[1];
  744.     i := 2;
  745.     WHILE i <= sortelements DO
  746.         Insert(sortlist[i],tree);
  747.         INC(i)
  748.     END;
  749.     IF ~ Checktree(tree) THEN Str(" Error in Tree.$") END;
  750. END Trees;
  751.     PROCEDURE Cos (x: REAL): REAL;
  752.     (* computes cos of x (x in radians) by an expansion *)
  753.         VAR i, factor: LONGINT;
  754.             result,power: REAL;
  755.     BEGIN
  756.         result := 1.0; factor := 1;  power := x; i := 2;
  757.         WHILE i <= 10 DO
  758.             factor := factor * i;  power := power*x;
  759.             IF i MOD 2 = 0 THEN
  760.                 IF i MOD 4 = 0 THEN result := result + power/factor
  761.                 ELSE result := result - power/factor
  762.                 END
  763.             END;
  764.             INC(i)
  765.         END ;
  766.         RETURN result
  767.     END Cos;
  768.     PROCEDURE Min0( arg1, arg2: LONGINT): LONGINT;
  769.     BEGIN
  770.         IF arg1 < arg2 THEN RETURN arg1
  771.         ELSE RETURN arg2
  772.         END
  773.     END Min0;
  774.     PROCEDURE Uniform11(iy: LONGINT; yfl: REAL);
  775.     BEGIN
  776.         iy := (4855*iy + 1731) MOD 8192;
  777.         yfl := iy/8192.0;
  778.     END Uniform11;
  779.     PROCEDURE Exptab(n: LONGINT; VAR e: c2array);
  780.         VAR theta, divisor: REAL; h: ARRAY 26 OF REAL;
  781.             i, j, k, l, m: LONGINT;
  782.     BEGIN
  783.         theta := 3.1415926536;
  784.         divisor := 4.0; i:=1;
  785.         WHILE i <= 25 DO
  786.             h[i] := 1/(2*Cos( theta/divisor ));
  787.             divisor := divisor + divisor;
  788.             INC(i)
  789.         END;
  790.         m := n DIV 2 ;
  791.         l := m DIV 2 ;
  792.         j := 1 ;
  793.         e[1].rp := 1.0 ;
  794.         e[1].ip := 0.0;
  795.         e[l+1].rp := 0.0;
  796.         e[l+1].ip := 1.0 ;
  797.         e[m+1].rp := -1.0 ;
  798.         e[m+1].ip := 0.0 ;
  799.         REPEAT
  800.             i := l DIV 2 ;
  801.             k := i ;
  802.             REPEAT
  803.                 e[k+1].rp := h[j]*(e[k+i+1].rp+e[k-i+1].rp) ;
  804.                 e[k+1].ip := h[j]*(e[k+i+1].ip+e[k-i+1].ip) ;
  805.                 k := k+l ;
  806.             UNTIL ( k > m );
  807.             j := Min0( j+1, 25);
  808.             l := i ;
  809.         UNTIL ( l <= 1 );
  810.     END Exptab;
  811.     PROCEDURE Fft( n: LONGINT; VAR z, w: carray; VAR e: c2array; sqrinv: REAL);
  812.         VAR i, j, k, l, m, index: LONGINT; h: REAL;
  813.     BEGIN
  814.         m := n DIV 2 ;
  815.         l := 1 ;
  816.         REPEAT
  817.             k := 0 ;
  818.             j := l ;
  819.             i := 1 ;
  820.             REPEAT
  821.                 REPEAT
  822.                     w[i+k].rp := z[i].rp+z[m+i].rp ;
  823.                     w[i+k].ip := z[i].ip+z[m+i].ip ;
  824.                     h := e[k+1].rp*(z[i].rp-z[i+m].rp);
  825.                     w[i+j].rp := h-e[k+1].ip*(z[i].ip-z[i+m].ip) ;
  826.                     h := e[k+1].rp*(z[i].ip-z[i+m].ip);
  827.                     w[i+j].ip := h+e[k+1].ip*(z[i].rp-z[i+m].rp) ;
  828.                     i := i+1 ;
  829.                 UNTIL ( i > j );
  830.                 k := j ;
  831.                 j := k+l ;
  832.             UNTIL ( j > m );
  833.             (*z := w ;*) index := 1;
  834.             REPEAT
  835.                 z[index] := w[index];
  836.                 index := index+1;
  837.             UNTIL ( index > n );
  838.             l := l+l ;
  839.         UNTIL ( l > m );
  840.         i := 1;
  841.         WHILE i <= n DO
  842.             z[i].rp := sqrinv*z[i].rp ;
  843.             z[i].ip := -sqrinv*z[i].ip;
  844.             INC(i)
  845.         END
  846.     END Fft;
  847. PROCEDURE* Oscar ();
  848.     VAR i: LONGINT;
  849. BEGIN
  850.     Exptab(fftsize,e) ;
  851.     seed := 5767 ; i := 1;
  852.     WHILE i <= fftsize DO
  853.         Uniform11( seed, zr );
  854.         Uniform11( seed, zi );
  855.         z[i].rp := 20.0*zr - 10.0;
  856.         z[i].ip := 20.0*zi - 10.0;
  857.         INC(i)
  858.     END ;
  859.     i := 1;
  860.     WHILE i <= 20 DO Fft(fftsize,z,w,e,0.0625); INC(i) END
  861. END Oscar;
  862. PROCEDURE Time(s: ARRAY OF CHAR; p: Proc; base, fbase: REAL);
  863.     VAR timer: LONGINT;
  864. BEGIN
  865.     Str(s);
  866.     timer := Getclock();
  867.     timer := Getclock()-timer;
  868.     Texts.WriteInt(W, timer, 8); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf);
  869.     fixed := fixed + timer*base;
  870.     floated := floated + timer*fbase
  871. END Time;
  872. PROCEDURE Do*;
  873. BEGIN
  874.     fixed := 0.0;  floated := 0.0;
  875.     Time("Perm ", Perm, permbase, permbase);
  876.     Time("Towers ", Towers, towersbase, towersbase);
  877.     Time("Queens ", Queens, queensbase, queensbase);
  878.     Time("Intmm ", Intmm, intmmbase, intmmbase);
  879.     Time("Mm ", Mm, mmbase, fpmmbase);
  880.     Time("Puzzle ", Puzzle, puzzlebase, puzzlebase);
  881.     Time("Quick ", Quick, quickbase, quickbase);
  882.     Time("Bubble ", Bubble, bubblebase, bubblebase);
  883.     Time("Tree ", Trees, treebase, treebase);
  884.     Time("FFT ", Oscar, fftbase, fpfftbase);
  885.     Str("Nonfloating point composite is "); Texts.WriteReal(W, fixed, 10); Texts.WriteLn(W);
  886.     Str("Floating point composite is "); Texts.WriteReal(W, floated, 10); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
  887. END Do;
  888. BEGIN
  889.     Texts.OpenWriter(W);
  890. END Hennessy.Do
  891.