72 lines
1.2 KiB
Plaintext
72 lines
1.2 KiB
Plaintext
MODULE AvgLoopLen;
|
|
(* Oxford Oberon-2 *)
|
|
IMPORT Random, Out;
|
|
|
|
PROCEDURE Fac(n: INTEGER; f: REAL): REAL;
|
|
BEGIN
|
|
IF n = 0 THEN
|
|
RETURN f
|
|
ELSE
|
|
RETURN Fac(n - 1,n*f)
|
|
END
|
|
END Fac;
|
|
|
|
PROCEDURE Power(n,i: INTEGER): REAL;
|
|
VAR
|
|
p: REAL;
|
|
BEGIN
|
|
p := 1.0;
|
|
WHILE i > 0 DO p := p * n; DEC(i) END;
|
|
RETURN p
|
|
END Power;
|
|
|
|
PROCEDURE Abs(x: REAL): REAL;
|
|
BEGIN
|
|
IF x < 0 THEN RETURN -x ELSE RETURN x END
|
|
END Abs;
|
|
|
|
PROCEDURE Analytical(n: INTEGER): REAL;
|
|
VAR
|
|
i: INTEGER;
|
|
res: REAL;
|
|
BEGIN
|
|
res := 0.0;
|
|
FOR i := 1 TO n DO
|
|
res := res + (Fac(n,1.0) / Power(n,i) / Fac(n - i,1.0));
|
|
END;
|
|
RETURN res
|
|
END Analytical;
|
|
|
|
PROCEDURE Averages(n: INTEGER): REAL;
|
|
CONST
|
|
times = 100000;
|
|
VAR
|
|
rnds: SET;
|
|
r,count,i: INTEGER;
|
|
BEGIN
|
|
count := 0; i := 0;
|
|
WHILE i < times DO
|
|
rnds := {};
|
|
LOOP
|
|
r := Random.Roll(n);
|
|
IF r IN rnds THEN EXIT ELSE INCL(rnds,r); INC(count) END
|
|
END;
|
|
INC(i)
|
|
END;
|
|
|
|
RETURN count / times
|
|
END Averages;
|
|
|
|
VAR
|
|
i: INTEGER;
|
|
av,an,df: REAL;
|
|
BEGIN
|
|
Random.Randomize;
|
|
Out.String(" Averages Analytical Diff% ");Out.Ln;
|
|
FOR i := 1 TO 20 DO
|
|
Out.Int(i,3); Out.String(": ");
|
|
av := Averages(i);an := Analytical(i);df := Abs(av - an) / an * 100.0;
|
|
Out.Fixed(av,10,4);Out.Fixed(an,11,4);Out.Fixed(df,10,4);Out.Ln
|
|
END
|
|
END AvgLoopLen.
|