Average loop length: Difference between revisions

added Easylang
m (→‎{{header|D}}: Fix link: Perl 6 --> Raku)
(added Easylang)
 
(36 intermediate revisions by 20 users not shown)
Line 36:
20 5.2699 5.2936 ( 0.45%)</pre>
<br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F ffactorial(n)
V result = 1.0
L(i) 2..n
result *= i
R result
 
V MAX_N = 20
V TIMES = 1000000
 
F analytical(n)
R sum((1..n).map(i -> ffactorial(@n) / pow(Float(@n), Float(i)) / ffactorial(@n - i)))
 
F test(n, times)
V count = 0
L(i) 0 .< times
V (x, bits) = (1, 0)
L (bits [&] x) == 0
count++
bits [|]= x
x = 1 << random:(n)
R Float(count) / times
 
print(" n avg exp. diff\n-------------------------------")
L(n) 1 .. MAX_N
V avg = test(n, TIMES)
V theory = analytical(n)
V diff = (avg / theory - 1) * 100
print(‘#2 #3.4 #3.4 #2.3%’.format(n, avg, theory, diff))</syntaxhighlight>
 
{{out}}
<pre>
n avg exp. diff
-------------------------------
1 1.0000 1.0000 0.000%
2 1.5003 1.5000 0.022%
3 1.8897 1.8889 0.044%
4 2.2170 2.2187 -0.080%
5 2.5099 2.5104 -0.022%
6 2.7736 2.7747 -0.040%
7 3.0182 3.0181 0.001%
8 3.2438 3.2450 -0.037%
9 3.4589 3.4583 0.018%
10 3.6605 3.6602 0.008%
11 3.8517 3.8524 -0.017%
12 4.0373 4.0361 0.032%
13 4.2159 4.2123 0.085%
14 4.3828 4.3820 0.017%
15 4.5465 4.5458 0.016%
16 4.7048 4.7043 0.013%
17 4.8585 4.8579 0.012%
18 5.0042 5.0071 -0.057%
19 5.1465 5.1522 -0.110%
20 5.2907 5.2936 -0.054%
</pre>
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;
with Ada.Numerics.Discrete_Random;
Line 90 ⟶ 148:
Put(err, Fore=>3, Aft=>3, exp=>0); New_line;
end loop;
end Avglen;</langsyntaxhighlight>
{{out}}
<pre>
Line 117 ⟶ 175:
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic"> @% = &2040A
MAX_N = 20
TIMES = 1000000
Line 149 ⟶ 207:
DEF FNfactorial(n)
IF n=1 OR n=0 THEN =1 ELSE = n * FNfactorial(n-1)</langsyntaxhighlight>
{{out}}
<pre>
Line 176 ⟶ 234:
=={{header|C}}==
 
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <math.h>
Line 231 ⟶ 289:
}
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 256 ⟶ 314:
19 5.1479 5.1522 -0.084%
20 5.2957 5.2936 0.040%
</pre>
 
=={{header|C sharp|C#}}==
{{trans|Java}}
<syntaxhighlight lang="csharp">public class AverageLoopLength {
private static int N = 100000;
private static double analytical(int n) {
double[] factorial = new double[n + 1];
double[] powers = new double[n + 1];
powers[0] = 1.0;
factorial[0] = 1.0;
for (int i = 1; i <= n; i++) {
factorial[i] = factorial[i - 1] * i;
powers[i] = powers[i - 1] * n;
}
double sum = 0;
for (int i = 1; i <= n; i++) {
sum += factorial[n] / factorial[n - i] / powers[i];
}
return sum;
}
 
private static double average(int n) {
Random rnd = new Random();
double sum = 0.0;
for (int a = 0; a < N; a++) {
int[] random = new int[n];
for (int i = 0; i < n; i++) {
random[i] = rnd.Next(n);
}
var seen = new HashSet<double>(n);
int current = 0;
int length = 0;
while (seen.Add(current)) {
length++;
current = random[current];
}
sum += length;
}
return sum / N;
}
public static void Main(string[] args) {
Console.WriteLine(" N average analytical (error)");
Console.WriteLine("=== ========= ============ =========");
for (int i = 1; i <= 20; i++) {
var average = AverageLoopLength.average(i);
var analytical = AverageLoopLength.analytical(i);
Console.WriteLine("{0,3} {1,10:N4} {2,13:N4} {3,8:N2}%", i, average, analytical, (analytical - average) / analytical * 100);
}
}
}
</syntaxhighlight>
{{out}}
<pre>
N average analytical (error)
=== ========= ============ =========
1 1.0000 1.0000 0.00%
2 1.4999 1.5000 0.01%
3 1.8860 1.8889 0.15%
4 2.2235 2.2188 -0.22%
5 2.5115 2.5104 -0.04%
6 2.7793 2.7747 -0.17%
7 3.0149 3.0181 0.11%
8 3.2457 3.2450 -0.02%
9 3.4559 3.4583 0.07%
10 3.6558 3.6602 0.12%
11 3.8428 3.8524 0.25%
12 4.0270 4.0361 0.22%
13 4.2111 4.2123 0.03%
14 4.3766 4.3820 0.12%
15 4.5535 4.5458 -0.17%
16 4.6989 4.7043 0.11%
17 4.8590 4.8579 -0.02%
18 4.9972 5.0071 0.20%
19 5.1542 5.1522 -0.04%
20 5.3024 5.2936 -0.17%
 
</pre>
 
=={{header|C++}}==
Partial translation of C using stl and std.
<langsyntaxhighlight lang="cpp">#include <random>
#include <random>
#include <vector>
#include <iostream>
Line 276 ⟶ 415:
int randint(int n) {
int r, rmax = RAND_MAX / n * n;
dis=std::uniform_int_distribution<int>(0,rmax) ;
r = dis(gen);
return r / (RAND_MAX / n);
}
 
unsigned long long factorial(size_t n) {
//Factorial using dynamic programming to memoize the values.
static std::vector<unsigned long long>factorials{1,1,2};
for (;factorials.size() <= n;)
factorials.push_back(((unsigned long long) factorials.back())*factorials.size());
return factorials[n];
}
Line 322 ⟶ 461:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
n avg exp. diff
-------------------------------
1 1.0000 1.0000 0.000002%
2 1.49984999 1.5000 -0.016006%
3 1.88838897 1.8889 - 0.032042%
4 2.21882177 2.2188 -0.000046%
5 2.51055109 2.5104 0.004018%
6 2.77607768 2.7747 0.047077%
7 3.01800187 3.0181 - 0.004019%
8 3.2448 3.2450 -0.007008%
9 3.45804600 3.4583 - 0.010049%
10 3.66146619 3.6602 0.032046%
11 3.85328526 3.8524 0.022006%
12 4.03490391 4.0361 - 0.029076%
13 4.21532129 4.2123 0.070012%
14 4.38193858 4.3820 - 0.003087%
15 4.54945469 4.5458 0.079023%
16 4.70827045 4.7043 0.084006%
17 4.85768587 4.8579 - 0.005016%
18 5.00280071 5.0071 - 0.084001%
19 5.14841529 5.1522 - 0.073013%
20 5.29392931 5.2936 -0.006010%
 
</pre>
Line 352 ⟶ 491:
=={{header|Clojure}}==
{{trans|Python}}
<langsyntaxhighlight lang="lisp">(ns cyclelengths
(:gen-class))
 
Line 396 ⟶ 535:
diff (Math/abs (* 100 (- 1 (/ avg anal))))]]
(println (format "%3d\t%.4f\t%.4f\t%.2f%%" q avg anal diff)))
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Line 424 ⟶ 563:
=={{header|D}}==
{{trans|Raku}}
<langsyntaxhighlight lang="d">import std.stdio, std.random, std.math, std.algorithm, std.range, std.format;
 
real analytical(in int n) pure nothrow @safe /*@nogc*/ {
Line 464 ⟶ 603:
n, average, an, errorS);
}
}</langsyntaxhighlight>
{{out}}
<pre> n average analytical (error)
Line 508 ⟶ 647:
39 7.51864 7.50959 ( 0.1204%)
40 7.60255 7.60911 ( 0.0863%)</pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| System.Math}}
{{Trans|C}}
<syntaxhighlight lang="delphi">
program Average_loop_length;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils,
System.Math;
 
const
MAX_N = 20;
TIMES = 1000000;
 
function Factorial(const n: Double): Double;
begin
Result := 1;
if n > 1 then
Result := n * Factorial(n - 1);
end;
 
function Expected(const n: Integer): Double;
var
i: Integer;
begin
Result := 0;
for i := 1 to n do
Result := Result + (factorial(n) / Power(n, i) / factorial(n - i));
end;
 
function Test(const n, times: Integer): integer;
var
i, x, bits: Integer;
begin
Result := 0;
for i := 0 to times - 1 do
begin
x := 1;
bits := 0;
while ((bits and x) = 0) do
begin
inc(Result);
bits := bits or x;
x := 1 shl random(n);
end;
end;
end;
 
var
n, cnt: Integer;
avg, theory, diff: Double;
 
begin
Randomize;
Writeln(#10' tavg'^I'exp.'^I'diff'#10'-------------------------------');
 
for n := 1 to MAX_N do
begin
cnt := test(n, times);
avg := cnt / times;
theory := expected(n);
diff := (avg / theory - 1) * 100;
writeln(format('%2d %8.4f %8.4f %6.3f%%', [n, avg, theory, diff]));
end;
 
readln;
end.
 
</syntaxhighlight>
 
{{out}}
<pre>
 
tavg exp. diff
-------------------------------
1 1,0000 1,0000 0,000%
2 1,4985 1,5000 -0,101%
3 1,8896 1,8889 0,037%
4 2,2195 2,2188 0,035%
5 2,5103 2,5104 -0,003%
6 2,7746 2,7747 -0,005%
7 3,0176 3,0181 -0,017%
8 3,2458 3,2450 0,023%
9 3,4572 3,4583 -0,032%
10 3,6623 3,6602 0,057%
11 3,8494 3,8524 -0,078%
12 4,0373 4,0361 0,029%
13 4,2114 4,2123 -0,023%
14 4,3834 4,3820 0,032%
15 4,5449 4,5458 -0,020%
16 4,7030 4,7043 -0,027%
17 4,8574 4,8579 -0,009%
18 5,0063 5,0071 -0,014%
19 5,1506 5,1522 -0,030%
20 5,2960 5,2936 0,046%
</pre>
=={{header|EasyLang}}==
{{trans|Lua}}
<syntaxhighlight>
func average n reps .
for r to reps
f[] = [ ]
for i to n
f[] &= randint n
.
seen[] = [ ]
len seen[] n
x = 1
while seen[x] = 0
seen[x] = 1
x = f[x]
count += 1
.
.
return count / reps
.
func analytical n .
s = 1
t = 1
for i = n - 1 downto 1
t = t * i / n
s += t
.
return s
.
print " N average analytical (error)"
print "=== ======= ========== ======="
for n to 20
avg = average n 1e6
ana = analytical n
err = (avg - ana) / ana * 100
numfmt 0 2
write n
numfmt 4 9
print avg & ana & err & "%"
.
</syntaxhighlight>
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
(lib 'math) ;; Σ aka (sigma f(n) nfrom nto)
Line 540 ⟶ 819:
(define fa (f-anal N))
(printf "%3d %10d %10d %10.2d %%" N fc fa (// (abs (- fa fc)) fc 0.01))))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 569 ⟶ 848:
{{trans|Ruby}}
{{works with|Elixir|1.1+}}
<langsyntaxhighlight lang="elixir">defmodule RC do
def factorial(0), do: 1
def factorial(n), do: Enum.reduce(1..n, 1, &(&1 * &2))
Line 594 ⟶ 873:
 
runs = 1_000_000
RC.task(runs)</langsyntaxhighlight>
 
{{out}}
Line 625 ⟶ 904:
{{trans|Scala}}
<p>But uses the Gamma function instead of factorials.</p>
<langsyntaxhighlight lang="fsharp">open System
 
let gamma z =
Line 674 ⟶ 953:
printfn "%2i %2.6f %2.6f %+2.3f%%" n avg theory ((avg / theory - 1.) * 100.))
0
</syntaxhighlight>
</lang>
{{out}}
<pre> N average analytical (error)
Line 702 ⟶ 981:
The <code>loop-length</code> word is more or less a translation of the inner loop of C's <code>test</code> function.
{{works with|Factor|0.99 2020-01-23}}
<langsyntaxhighlight lang="factor">USING: formatting fry io kernel locals math math.factorials
math.functions math.ranges random sequences ;
 
Line 726 ⟶ 1,005:
 
" n\tavg\texp.\tdiff\n-------------------------------" print
20 [1,b] [ .line ] each</langsyntaxhighlight>
{{out}}
<pre>
Line 751 ⟶ 1,030:
19 5.1519 5.1522 -0.005%
20 5.2927 5.2936 -0.017%
</pre>
 
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">Const max_N = 20, max_ciclos = 1000000
 
Function Factorial(Byval N As Integer) As Double
Dim As Double d: d = 1
If N = 0 Then Factorial = 1: Exit Function
While (N > 1)
d *= N
N -= 1
Wend
Factorial = d
End Function
 
Function Analytical(N As Integer) As Double
Dim As Double i, sum = 0
For i = 1 To N
sum += Factorial(N) / N^i / Factorial(N-i)
Next i
Return sum
End Function
 
Function Average(N As Integer, ciclos As Double) As Double
Dim As Integer i, x, bits, sum = 0
For i = 0 To ciclos - 1
x = 1 : bits = 0
While (bits And x) = 0
sum += 1
bits Or= x
x = 1 Shl (Rnd * (N - 1))
Wend
Next i
Return sum / ciclos
End Function
 
Randomize Timer
Print " N promedio analitico (error)"
Print "--- ---------- ----------- ----------"
For N As Integer = 1 To max_N
Dim As Double avg = Average(N, max_ciclos)
Dim As Double ana = Analytical(N)
Dim As Double diff = abs(avg-ana) / ana * 100
Print Using " ## #####.###0 #####.###0 ###.#0%"; N; avg; ana; diff
Next N
Sleep
</syntaxhighlight>
 
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
_nmax = 20
_times = 1000000
 
local fn Average( n as long, times as long ) as double
long i, x
double b, c = 0
for i = 0 to times
x = 1 : b = 0
while ( b and x ) == 0
c++
b = b || x
x = 1 << ( rnd(n) - 1 )
wend
next
end fn = c / times
 
local fn Analyltic( n as long ) as double
double nn = (double)n
double term = 1.0
double sum = 1.0
long i
for i = nn - 1 to i >= 1 step -1
term = term * i / nn
sum = sum + term
next
end fn = sum
 
local fn DoIt
long n
double average, theory, difference
window 1
printf @"\nSamples tested: %ld\n", _times
print " N Average Analytical (error)"
print "=== ========= ============ ========="
for n = 1 to _nmax
average = fn Average( n, _times )
theory = fn Analyltic( n )
difference = ( average / theory - 1) * 100
printf @"%3d %9.4f %9.4f %10.4f%%", n, average, theory, difference
next
end fn
 
randomize
fn DoIt
 
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
Number of tests performed: 1000000
 
N Average Analytical (error)
=== ========= ============ =========
1 1.0000 1.0000 0.0001%
2 1.4999 1.5000 -0.0070%
3 1.8877 1.8889 -0.0630%
4 2.2187 2.2188 -0.0011%
5 2.5102 2.5104 -0.0065%
6 2.7735 2.7747 -0.0438%
7 3.0173 3.0181 -0.0273%
8 3.2478 3.2450 0.0854%
9 3.4569 3.4583 -0.0424%
10 3.6604 3.6602 0.0060%
11 3.8506 3.8524 -0.0449%
12 4.0361 4.0361 0.0003%
13 4.2148 4.2123 0.0582%
14 4.3845 4.3820 0.0559%
15 4.5454 4.5458 -0.0079%
16 4.7056 4.7043 0.0288%
17 4.8558 4.8579 -0.0428%
18 5.0143 5.0071 0.1450%
19 5.1509 5.1522 -0.0254%
20 5.2985 5.2936 0.0929%
</pre>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 797 ⟶ 1,204:
}
return sum
}</langsyntaxhighlight>
{{out}}
<pre>
Line 825 ⟶ 1,232:
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">import System.Random
import qualified Data.Set as S
import Text.Printf
Line 878 ⟶ 1,285:
range = [1..20] :: [Integer]
_ <- test samples range $ mkStdGen 0
return ()</langsyntaxhighlight>
<pre> N average analytical (error)
=== ========= ============ =========
Line 908 ⟶ 1,315:
 
We can implement f as {&LIST where LIST is an arbitrary list of N numbers, each picked independently from the range 0..(N-1). We can incrementally build the described sequence using (, f@{:) - here we extend the sequence by applying f to the last element of the sequence. Since we are only concerned with the sequence up to the point of the first repeat, we can select the unique values giving us (~.@, f@{:). This routine stops changing when we reach the desired length, so we can repeatedly apply it forever. For example:
<langsyntaxhighlight Jlang="j"> (~.@, {&0 0@{:)^:_] 0
0
(~.@, {&0 0@{:)^:_] 1
1 0</langsyntaxhighlight>
Once we have the sequence, we can count how many elements are in it.
<langsyntaxhighlight Jlang="j"> 0 0 ([: # (] ~.@, {:@] { [)^:_) 1
2</langsyntaxhighlight>
Meanwhile, we can also generate all possible values of 1..N by counting out N^N values and breaking out the result as a base N list of digits.
<langsyntaxhighlight Jlang="j"> (#.inv i.@^~)2
0 0
0 1
1 0
1 1</langsyntaxhighlight>
All that's left is to count the lengths of all possible sequences for all possible distinct instances of f and average the results:
<langsyntaxhighlight Jlang="j"> (+/ % #)@,@((#.inv i.@^~) ([: # (] ~.@, {:@] { [)^:_)"1 0/ i.)1
1
(+/ % #)@,@((#.inv i.@^~) ([: # (] ~.@, {:@] { [)^:_)"1 0/ i.)2
Line 933 ⟶ 1,340:
2.5104
(+/ % #)@,@((#.inv i.@^~) ([: # (] ~.@, {:@] { [)^:_)"1 0/ i.)6
2.77469</langsyntaxhighlight>
Meanwhile the analytic solution (derived by reading the Ada implementation) looks like this:
<langsyntaxhighlight Jlang="j"> ana=: +/@(!@[ % !@- * ^) 1+i.
ana"0]1 2 3 4 5 6
1 1.5 1.88889 2.21875 2.5104 2.77469</langsyntaxhighlight>
To get our simulation, we can take the exact approach and replace the part that generates all possible values for f with a random mechanism. Since the task does not specify how long to run the simulation, and to make this change easy, we'll use N*1e4 tests.
<langsyntaxhighlight Jlang="j"> sim=: (+/ % #)@,@((]?@$~1e4,]) ([: # (] ~.@, {:@] { [)^:_)"1 0/ i.)
sim"0]1 2 3 4 5 6
1 1.5034 1.8825 2.22447 2.51298 2.76898</langsyntaxhighlight>
The simulation approach is noticeably slower than the analytic approach, while being less accurate.
 
Finally, we can generate our desired results:
<langsyntaxhighlight Jlang="j"> (;:'N average analytic error'),:,.each(;ana"0 ([;];-|@%[) sim"0)1+i.20
+--+-------+--------+-----------+
|N |average|analytic|error |
Line 969 ⟶ 1,376:
|19| 5.1522|5.14785 |0.000843052|
|20|5.29358|5.28587 | 0.00145829|
+--+-------+--------+-----------+</langsyntaxhighlight>
Here, error is the difference between the two values divided by the analytic value.
 
Line 976 ⟶ 1,383:
This uses a 0-based index (0, 1, ..., n-1) as opposed to the 1-based index (1, 2, ..., n) specified in the question, because it fits better with the native structure of Java.
 
<langsyntaxhighlight lang="java">import java.util.HashSet;
import java.util.Random;
import java.util.Set;
Line 1,031 ⟶ 1,438:
}
}
}</langsyntaxhighlight>
 
=={{header|Julia}}==
{{trans|Python}}
<langsyntaxhighlight lang="julia">using Printf
 
analytical(n::Integer) = sum(factorial(n) / big(n) ^ i / factorial(n - i) for i = 1:n)
Line 1,063 ⟶ 1,470:
 
main(20)
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,093 ⟶ 1,500:
=={{header|Kotlin}}==
{{trans|Go}}
<langsyntaxhighlight lang="scala">const val NMAX = 20
const val TESTS = 1000000
val rand = java.util.Random()
Line 1,130 ⟶ 1,537:
println(String.format("%3d %6.4f %10.4f (%4.2f%%)", n, a, b, Math.abs(a - b) / b * 100.0))
}
}</langsyntaxhighlight>
Sample output:
{{out}}
Line 1,160 ⟶ 1,567:
=={{header|Liberty BASIC}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="lb">
<lang lb>
MAXN = 20
TIMES = 10000'00
Line 1,197 ⟶ 1,604:
IF n=1 OR n=0 THEN FNfactorial=1 ELSE FNfactorial= n * FNfactorial(n-1)
end function
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,222 ⟶ 1,629:
20 5.2792 5.29358459 -0.2717%
</pre>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">function average(n, reps)
local count = 0
for r = 1, reps do
local f = {}
for i = 1, n do f[i] = math.random(n) end
local seen, x = {}, 1
while not seen[x] do
seen[x], x, count = true, f[x], count+1
end
end
return count / reps
end
 
function analytical(n)
local s, t = 1, 1
for i = n-1, 1, -1 do t=t*i/n s=s+t end
return s
end
 
print(" N average analytical (error)")
print("=== ========= ============ =========")
for n = 1, 20 do
local avg, ana = average(n, 1e6), analytical(n)
local err = (avg-ana) / ana * 100
print(string.format("%3d %9.4f %12.4f (%6.3f%%)", n, avg, ana, err))
end</syntaxhighlight>
{{out}}
<pre> N average analytical (error)
=== ========= ============ =========
1 1.0000 1.0000 ( 0.000%)
2 1.5002 1.5000 ( 0.014%)
3 1.8896 1.8889 ( 0.037%)
4 2.2176 2.2188 (-0.054%)
5 2.5094 2.5104 (-0.038%)
6 2.7732 2.7747 (-0.054%)
7 3.0186 3.0181 ( 0.016%)
8 3.2440 3.2450 (-0.031%)
9 3.4554 3.4583 (-0.085%)
10 3.6625 3.6602 ( 0.063%)
11 3.8534 3.8524 ( 0.026%)
12 4.0354 4.0361 (-0.016%)
13 4.2111 4.2123 (-0.031%)
14 4.3839 4.3820 ( 0.043%)
15 4.5453 4.5458 (-0.012%)
16 4.7054 4.7043 ( 0.024%)
17 4.8596 4.8579 ( 0.035%)
18 5.0099 5.0071 ( 0.056%)
19 5.1553 5.1522 ( 0.060%)
20 5.2901 5.2936 (-0.066%)</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight lang="mathematica">Grid@Prepend[
Table[{n, #[[1]], #[[2]],
Row[{Round[10000 Abs[#[[1]] - #[[2]]]/#[[2]]]/100., "%"}]} &@
Line 1,232 ⟶ 1,690:
RandomInteger[{1, n}, n]] &] &, 10000]],
Sum[n! n^(n - k - 1)/(n - k)!, {k, n}]/n^(n - 1)}, 5], {n, 1,
20}], {"N", "average", "analytical", "error"}]</langsyntaxhighlight>
{{Out}}
<pre>N average analytical error
Line 1,258 ⟶ 1,716:
=={{header|Nim}}==
{{trans|C}}
<langsyntaxhighlight lang="nim">import random, math, strfmtstrformat
randomize()
Line 1,282 ⟶ 1,740:
inc result
bits = bits or x
x = 1 shl randomrand(n - 1)
echo " n\tavg\texp.\tdiff"
Line 1,291 ⟶ 1,749:
let theory = expected(n)
let diff = (avg / theory - 1) * 100
printlnfmtecho fmt"{n:2} {avg:8.4f} {theory:8.4f} {diff:6.3f}%", n, avg, theory, diff</langsyntaxhighlight>
{{out}}
<pre> n avg exp. diff
Line 1,317 ⟶ 1,775:
 
=={{header|Oberon-2}}==
<langsyntaxhighlight lang="oberon2">
MODULE AvgLoopLen;
(* Oxford Oberon-2 *)
Line 1,389 ⟶ 1,847:
END
END AvgLoopLen.
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 1,417 ⟶ 1,875:
=={{header|PARI/GP}}==
{{trans|C}}
<langsyntaxhighlight lang="parigp">expected(n)=sum(i=1,n,n!/(n-i)!/n^i,0.);
test(n, times)={
my(ct);
Line 1,430 ⟶ 1,888:
my(cnt=test(n, TIMES),avg=cnt/TIMES,ex=expected(n),diff=(avg/ex-1)*100.);
print(n"\t"avg*1."\t"ex*1."\t"diff);
)}</langsyntaxhighlight>
{{out}}
<pre>1 1.0000 1.0000 0.E-7
Line 1,454 ⟶ 1,912:
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use List::Util qw(sum reduce);
 
sub find_loop {
Line 1,474 ⟶ 1,932:
printf "%3d %9.4f %12.4f (%5.2f%%)\n",
$n, $empiric, $theoric, 100 * ($empiric - $theoric) / $theoric;
}</langsyntaxhighlight>
{{out}}
<pre> N empiric theoric (error)
Line 1,500 ⟶ 1,958:
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>constant MAX = 20,
<span style="color: #008080;">constant</span> <span style="color: #000000;">MAX</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">20</span><span style="color: #0000FF;">,</span>
ITER = 1000000
<span style="color: #000000;">ITER</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1000000</span>
 
function expected(integer n)
<span style="color: #008080;">function</span> <span style="color: #000000;">expected</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
atom sum = 0
<span style="color: #004080;">atom</span> <span style="color: #7060A8;">sum</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
for i=1 to n do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
sum += factorial(n) / power(n,i) / factorial(n-i)
<span style="color: #7060A8;">sum</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">/</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">/</span> <span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
return sum
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sum</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function test(integer n)
<span style="color: #008080;">function</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
integer count = 0, x, bits
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">bits</span>
for i=1 to ITER do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">ITER</span> <span style="color: #008080;">do</span>
x = 1
<span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
bits = 0
<span style="color: #000000;">bits</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
while not and_bits(bits,x) do
<span style="color: #008080;">while</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bits</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
count += 1
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
bits = or_bits(bits,x)
<span style="color: #000000;">bits</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">or_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bits</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
x = power(2,rand(n)-1)
<span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
return count/ITER
<span style="color: #008080;">return</span> <span style="color: #000000;">count</span><span style="color: #0000FF;">/</span><span style="color: #000000;">ITER</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
atom av, ex
<span style="color: #004080;">atom</span> <span style="color: #000000;">av</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ex</span>
puts(1," n avg. exp. (error%)\n");
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" n avg. exp. (error%)\n"</span><span style="color: #0000FF;">);</span>
puts(1,"== ====== ====== ========\n");
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"== ====== ====== ========\n"</span><span style="color: #0000FF;">);</span>
for n=1 to MAX do
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">MAX</span> <span style="color: #008080;">do</span>
av = test(n)
<span style="color: #000000;">av</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
ex = expected(n)
<span style="color: #000000;">ex</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">expected</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
printf(1,"%2d %8.4f %8.4f (%5.3f%%)\n", {n,av,ex,abs(1-av/ex)*100})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%2d %8.4f %8.4f (%5.3f%%)\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">av</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ex</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">av</span><span style="color: #0000FF;">/</span><span style="color: #000000;">ex</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">100</span><span style="color: #0000FF;">})</span>
end for</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,558 ⟶ 2,018:
20 5.2955 5.2936 (0.037%)
</pre>
 
=={{header|Phixmonti}}==
{{trans|Phix}}
<syntaxhighlight lang="phixmonti">include ..\Utilitys.pmt
 
20 var MAX
100000 var ITER
 
def factorial 1 swap for * endfor enddef
 
def expected /# n -- n #/
>ps
0
tps for var i
tps factorial tps i power / tps i - factorial / +
endfor
ps> drop
enddef
 
def condition over over bitand not enddef
 
def test /# n -- n #/
0 >ps
ITER for var i
0 1
condition while
ps> 1 + >ps
bitor
over rand * 1 + int 1 - 2 swap power
condition endwhile
drop drop
endfor
drop ps> ITER /
enddef
 
def printAll len for get print 9 tochar print endfor enddef
 
( "n" "avg." "exp." "(error%)" ) printAll drop nl
( "==" "======" "======" "========" ) printAll drop nl
 
MAX for var n
n test
n expected
n rot rot over over / 1 swap - abs 100 * 4 tolist printAll drop nl
endfor</syntaxhighlight>
{{out}}
<pre>n avg. exp. (error%)
== ====== ====== ========
1 1 1 0
2 1.50119 1.5 0.0793333
3 1.89076 1.88889 0.0990588
4 2.22164 2.21875 0.130254
5 2.50989 2.5104 0.0203155
6 2.78108 2.77469 0.230247
7 3.02431 3.01814 0.204474
8 3.24594 3.24502 0.0284126
9 3.46167 3.45832 0.096991
10 3.66691 3.66022 0.182894
11 3.84558 3.85237 0.176308
12 4.03174 4.03607 0.107374
13 4.21113 4.21235 0.0289129
14 4.37294 4.38203 0.207425
15 4.54199 4.54581 0.0839738
16 4.69651 4.70426 0.164707
17 4.8463 4.85787 0.238187
18 5.01786 5.00706 0.215633
19 5.15783 5.1522 0.109348
20 5.29575 5.29358 0.0409064
 
=== Press any key to exit ===</pre>
 
=={{header|PicoLisp}}==
{{trans|Python}}
<langsyntaxhighlight PicoLisplang="picolisp">(scl 4)
(seed (in "/dev/urandom" (rd 8)))
 
Line 1,602 ⟶ 2,132:
2 ) ) ) ) )
 
(bye)</langsyntaxhighlight>
 
=={{header|PowerShell}}==
{{works with|PowerShell|2}}
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Get-AnalyticalLoopAverage ( [int]$N )
{
Line 1,666 ⟶ 2,196:
return $LoopAvereage
}
</syntaxhighlight>
</lang>
Note: The use of the [pscustomobject] type accelerator to simplify making the test result table look pretty requires PowerShell 3.0.
<syntaxhighlight lang="powershell">
<lang PowerShell>
# Display results for N = 1 through 20
ForEach ( $N in 1..20 )
Line 1,681 ⟶ 2,211:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,710 ⟶ 2,240:
=={{header|Python}}==
{{trans|C}}
<langsyntaxhighlight lang="python">from __future__ import division # Only necessary for Python 2.X
from math import factorial
from random import randrange
Line 1,736 ⟶ 2,266:
theory = analytical(n)
diff = (avg / theory - 1) * 100
print("%2d %8.4f %8.4f %6.3f%%" % (n, avg, theory, diff))</langsyntaxhighlight>
{{out}}
<pre> n avg exp. diff
Line 1,760 ⟶ 2,290:
19 5.1534 5.1522 0.024%
20 5.2927 5.2936 -0.017%</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="Quackery"> [ $ "bigrat.qky" loadfile ] now!
 
[ tuck space swap of
join
swap split drop echo$ ] is lecho$ ( $ n --> )
 
[ 1 swap times [ i 1+ * ] ] is ! ( n --> n )
 
[ 0 n->v rot
dup temp put
times
[ temp share ! n->v
temp share i 1+ - ! n->v
v/
temp share i 1+ ** n->v
v/ v+ ]
temp release ] is expected ( n --> n/d )
 
[ -1 temp put
0
[ 1 temp tally
over random bit
2dup & not while
| again ]
2drop drop
temp take ] is trial ( n --> n )
 
[ tuck 0 swap
times
[ over trial + ]
nip swap reduce ] is trials ( n n --> n/d )
 
[ say " n average expected difference"
cr
say "-- ------- -------- ----------"
cr
20 times
[ i^ 1+ dup 10 < if sp echo
2 times sp
i^ 1+ 1000000 trials
2dup 7 point$ 10 lecho$
i^ 1+ expected
2dup 7 point$ 11 lecho$
v/ 1 n->v v- 100 1 v* vabs
7 point$ echo$ say "%" cr ] ] is task ( --> )</syntaxhighlight>
 
{{out}}
 
<pre> n average expected difference
-- ------- -------- ----------
1 1 1 0%
2 1.499195 1.5 0.0536667%
3 1.88936 1.8888889 0.0249412%
4 2.220728 2.21875 0.0891493%
5 2.508183 2.5104 0.0883126%
6 2.773072 2.7746914 0.0583617%
7 3.019331 3.0181387 0.0395045%
8 3.243534 3.245018 0.0457318%
9 3.45625 3.4583157 0.0597327%
10 3.658848 3.6602157 0.0373661%
11 3.850874 3.8523721 0.0388865%
12 4.032375 4.0360737 0.0916404%
13 4.212238 4.2123479 0.0026093%
14 4.383076 4.3820294 0.0238834%
15 4.544029 4.5458073 0.0391192%
16 4.706797 4.7042582 0.0539671%
17 4.856011 4.8578708 0.0382847%
18 5.004107 5.0070631 0.0590386%
19 5.152561 5.1521962 0.0070805%
20 5.288056 5.2935846 0.1044394%
</pre>
 
=={{header|R}}==
<syntaxhighlight lang="r">
<lang R>
expected <- function(size) {
result <- 0
Line 1,797 ⟶ 2,401:
cat(sprintf("%3d%11.4f%14.4f ( %4.4f%%)\n", num, round(average,4), round(analytical,4), round(error,2)))
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,826 ⟶ 2,430:
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(require (only-in math factorial))
Line 1,854 ⟶ 2,458:
 
(test-table 20 10000)
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,884 ⟶ 2,488:
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>constant MAX_N = 20;
{{Works with|rakudo|2016.08}}
<lang perl6>constant MAX_N = 20;
constant TRIALS = 100;
for 1 .. MAX_N -> $N {
my $empiric = TRIALS R/ [+] find-loop(random-mapping( $N)).elems xx TRIALS;
my $theoric = [+]
map -> $k { $N ** ($k + 1) R/ [*×] flat $k**2, $N - $k + 1 .. $N }, 1 .. $N;
FIRST say " N empiric theoric (error)";
Line 1,897 ⟶ 2,500:
printf "%3d %9.4f %12.4f (%4.2f%%)\n",
$N, $empiric, $theoric, 100 × abs($theoric - $empiric) / $theoric;
$theoric, 100 * abs($theoric - $empiric) / $theoric;
}
sub random-mapping { hash .list Z=> .roll($_) given ^$^size }
sub find-loop { 0, | %^mapping{*} ...^ { (%){$_}++ } }</langsyntaxhighlight>
{{out|Example}}
<pre> N empiric theoric (error)
Line 1,932 ⟶ 2,534:
 
Also note that the &nbsp; <big>'''!'''</big> &nbsp; (factorial function) &nbsp; uses memoization for optimization.
<langsyntaxhighlight lang="rexx">/*REXX program computes the average loop length mapping a random field 1···N ───► 1···N */
parse arg runs tests seed . /*obtain optional arguments from the CL*/
if runs =='' | runs =="," then runs = 40 /*Not specified? Then use the default.*/
Line 1,967 ⟶ 2,569:
/*──────────────────────────────────────────────────────────────────────────────────────*/
fmtD: parse arg y,d; d=word(d 4, 1); y=format(y, , d); parse var y w '.' f
if f=0 then return w || left('', d +1); return y</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre style="height:90ex">
Line 2,017 ⟶ 2,619:
40 7.6151 7.6091 0.0789
═══ ═════════ ═════════ ═════════
</pre>
 
=={{header|RPL}}==
This task is an opportunity to showcase several useful instructions - <code>CON, SEQ</code> and <code>∑</code> - which avoid to use a <code>FOR..NEXT</code> loop, to create a constant array, to generate a list of random numbers and to calculate a finite sum.
{{works with|HP|48G}}
« 0 → n times count
« 1 times '''FOR''' j
n { } + 0 CON
« n RAND * CEIL » 'z' 1 n 1 SEQ
1
'''WHILE''' 3 PICK OVER GET NOT '''REPEAT'''
ROT OVER 1 PUT ROT ROT
OVER SWAP GET
'count' 1 STO+
'''END''' 3 DROPN
'''NEXT'''
count times /
» » '<span style="color:blue">XPRMT</span>' STO
« { } DUP
1 20 '''FOR''' n
SWAP n 1000 <span style="color:blue">XPRMT</span> +
SWAP 'j' 1 n 'n!/n^j/(n-j)!' ∑ +
'''NEXT'''
DUP2 SWAP %CH ABS 2 FIX "%" ADD STD
» '<span style="color:blue">TASK</span>' STO
{{out}}
<pre>
3: { 1 1.497 1.882 2.2 2.468 2.823 3 3.258 3.475 3.647 3.854 4.003 4.234 4.46 4.589 4.767 4.852 4.929 5.154 5.251 }
2: { 1 1.5 1.88888888889 2.21875 2.5104 2.77469135802 3.0181387007 3.24501800538 3.45831574488 3.66021568 3.85237205073 4.03607367511 4.21234791298 4.38202942438 4.54580728514 4.70425824709 4.85787082081 5.00706309901 5.15219620097 5.29358458601 }
1:{ "0.00%" "0.20%" "0.36%" "0.85%" "1.69%" "1.74%" "0.60%" "0.40%" "0.48%" "0.36%" "0.04%" "0.82%" "0.51%" "1.78%" "0.95%" "1.33%" "0.12%" "1.56%" "0.04%" "0.80%" }
</pre>
 
=={{header|Ruby}}==
Ruby does not have a factorial method, not even in it's math library.
<langsyntaxhighlight lang="ruby">class Integer
def factorial
self == 0 ? 1 : (1..self).inject(:*)
Line 2,045 ⟶ 2,678:
analytical = (1..n).inject(0){|sum, i| sum += (n.factorial / (n**i).to_f / (n-i).factorial)}
puts "%3d %8.4f %8.4f (%8.4f%%)" % [n, avg, analytical, (avg/analytical - 1)*100]
end</langsyntaxhighlight>
{{out}}
<pre>
Line 2,074 ⟶ 2,707:
=={{header|Rust}}==
{{libheader|rand}}
<langsyntaxhighlight lang="rust">extern crate rand;
 
use rand::{ThreadRng, thread_rng};
Line 2,150 ⟶ 2,783:
 
 
</syntaxhighlight>
</lang>
{{out}}
Using default arguments:
Line 2,180 ⟶ 2,813:
=={{header|Scala}}==
 
<syntaxhighlight lang="scala">
<lang Scala>
import scala.util.Random
 
Line 2,217 ⟶ 2,850:
 
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,246 ⟶ 2,879:
=={{header|Scheme}}==
 
<langsyntaxhighlight lang="scheme">
(import (scheme base)
(scheme write)
Line 2,303 ⟶ 2,936:
(newline)))
(iota 20 1))
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,332 ⟶ 2,965:
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "float.s7i";
 
Line 2,395 ⟶ 3,028:
analytical digits 4 lpad 7 <& err digits 3 lpad 7);
end for;
end func;</langsyntaxhighlight>
 
{{out}}
Line 2,424 ⟶ 3,057:
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">func find_loop(n) {
var seen = Hash()
loop {
Line 2,445 ⟶ 3,078:
printf("%3d %9.4f %12.4f (%5.2f%%)\n",
n, empiric, theoric, 100*(empiric-theoric)/theoric)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,473 ⟶ 3,106:
 
=={{header|Simula}}==
<langsyntaxhighlight lang="simula">BEGIN
 
REAL PROCEDURE FACTORIAL(N); INTEGER N;
Line 2,537 ⟶ 3,170:
END FOR I;
END;
END</langsyntaxhighlight>
{{in}}
<pre>678</pre>
Line 2,564 ⟶ 3,197:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl"># Generate a list of the numbers increasing from $a to $b
proc range {a b} {
for {set result {}} {$a <= $b} {incr a} {lappend result $a}
Line 2,603 ⟶ 3,236:
set e [Experimental $n 100000]
puts [format "%3d %9.4f %12.4f (%6.2f%%)" $n $e $a [expr {abs($e-$a)/$a*100.0}]]
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,629 ⟶ 3,262:
20 5.2992 5.2936 ( 0.11%)
</pre>
 
=={{header|uBasic/4tH}}==
{{trans|BBC BASIC}}
This is about the limit of what you can do with uBasic/4tH. Since it is an integer BASIC, it uses what has become known in the Forth community as "Brodie math". The last 14 bits of an 64-bit integer are used to represent the fraction, so basically it is a form of "fixed point math". This, of course, leads inevitably to rounding errors. After step 14 the number is too large to fit in a 64-bit integer - so at that point it simply breaks down. Performance is another issue.
 
<syntaxhighlight lang="uBasic/4tH">M = 14
T = 100000
 
If Info("wordsize") < 64 Then Print "This program requires a 64-bit uBasic" : End
 
Print "N\tavg\tcalc\t%diff"
 
For n = 1 To M
a = FUNC(_Test(n, T))
h = FUNC(_Analytical(n))
d = FUNC(_Fmul(FUNC(_Fdiv(a, h)) - FUNC(_Ntof(1)), FUNC(_Ntof(100))))
 
Print n; "\t";
Proc _Fprint (a) : Print "\t";
Proc _Fprint (h) : Print "\t";
Proc _Fprint (d) : Print "%"
Next
End
 
_Analytical
Param (1)
Local (3)
 
c@ = 0
For b@ = 1 To a@
d@ = FUNC(_Fdiv(FUNC(_Factorial(a@)), a@^b@))
c@ = c@ + FUNC(_Fdiv (d@, FUNC(_Ntof(FUNC(_Factorial(a@-b@))))))
Next
Return (c@)
 
_Test
Param (2)
Local (4)
 
e@ = 0
For c@ = 1 To b@
f@ = 1 : d@ = 0
Do While AND(d@, f@) = 0
e@ = e@ + 1
d@ = OR(d@, f@)
f@ = SHL(1, Rnd(a@))
Loop
Next
Return (FUNC(_Fdiv(e@, b@)))
 
_Factorial
Param(1)
 
If (a@ = 1) + (a@ = 0) Then Return (1)
Return (a@ * FUNC(_Factorial(a@-1)))
 
_Fmul Param (2) : Return ((a@*b@)/16384)
_Fdiv Param (2) : Return ((a@*16384)/b@)
_Ftoi Param (1) : Return ((10000*a@)/16384)
_Itof Param (1) : Return ((16384*a@)/10000)
_Ntof Param (1) : Return (16384*a@)
_Fprint Param (1) : a@ = FUNC(_Ftoi(a@)) : Print Using "+?.####";a@; : Return</syntaxhighlight>
{{Out}}
<pre>N avg calc %diff
1 1.0000 1.0000 0.0000%
2 1.4985 1.5000 -0.0976%
3 1.8869 1.8887 -0.1037%
4 2.2192 2.2187 0.0183%
5 2.5130 2.5103 0.1037%
6 2.7761 2.7745 0.0549%
7 3.0264 3.0180 0.2746%
8 3.2504 3.2449 0.1647%
9 3.4528 3.4581 -0.1525%
10 3.6651 3.6599 0.1403%
11 3.8543 3.8521 0.0549%
12 4.0364 4.0357 0.0122%
13 4.2153 4.2119 0.0793%
14 4.3866 4.3815 0.1098%
 
0 OK, 0:392</pre>
 
=={{header|Unicon}}==
{{trans|C}}
<langsyntaxhighlight lang="unicon">link printf, factors
 
$define MAX_N 20
Line 2,670 ⟶ 3,383:
}
return 0
end</langsyntaxhighlight>
{{out}}
<pre> n avg exp. diff
Line 2,697 ⟶ 3,410:
=={{header|VBA}}==
{{trans|Phix}}
<langsyntaxhighlight lang="vb">Const MAX = 20
Const ITER = 1000000
Line 2,733 ⟶ 3,446:
Debug.Print Format(ex, "0.0000"); " ("; Format(Abs(1 - av / ex), "0.000%"); ")"
Next n
End Sub</langsyntaxhighlight>{{out}}
<pre> n avg. exp. (error%)
== ====== ====== ========
Line 2,756 ⟶ 3,469:
19 5,1530 5,1522 (0,016%)
20 5,2958 5,2936 (0,041%)</pre>
 
=={{header|VBScript}}==
Ported from the VBA version. I added some precalculations to speed it up
<syntaxhighlight lang="vb">
Const MAX = 20
Const ITER = 100000
Function expected(n)
Dim sum
ni=n
For i = 1 To n
sum = sum + fact(n) / ni / fact(n-i)
ni=ni*n
Next
expected = sum
End Function
Function test(n )
Dim coun,x,bits
For i = 1 To ITER
x = 1
bits = 0
Do While Not bits And x
count = count + 1
bits = bits Or x
x =shift(Int(n * Rnd()))
Loop
Next
test = count / ITER
End Function
 
'VBScript formats numbers but does'nt align them!
function rf(v,n,s) rf=right(string(n,s)& v,n):end function
'some precalculations to speed things up...
dim fact(20),shift(20)
fact(0)=1:shift(0)=1
for i=1 to 20
fact(i)=i*fact(i-1)
shift(i)=2*shift(i-1)
next
 
Dim n
Wscript.echo "For " & ITER &" iterations"
Wscript.Echo " n avg. exp. (error%)"
Wscript.Echo "== ====== ====== =========="
For n = 1 To MAX
av = test(n)
ex = expected(n)
Wscript.Echo rf(n,2," ")& " "& rf(formatnumber(av, 4),7," ") & " "& _
rf(formatnumber(ex,4),6," ")& " ("& rf(Formatpercent(1 - av / ex,4),8," ") & ")"
Next
</syntaxhighlight>
Output
<pre>
For 100000 iterations
n avg. exp. (error%)
== ====== ====== ==========
1 1.0000 1.0000 ( 0.0000%)
2 1.4982 1.5000 ( 0.0012%)
3 1.8909 1.8889 (-0.0010%)
4 2.2190 2.2188 (-0.0001%)
5 2.5102 2.5104 ( 0.0001%)
6 2.7789 2.7747 (-0.0015%)
7 3.0230 3.0181 (-0.0016%)
8 3.2449 3.2450 ( 0.0000%)
9 3.4543 3.4583 ( 0.0012%)
10 3.6714 3.6602 (-0.0031%)
11 3.8559 3.8524 (-0.0009%)
12 4.0345 4.0361 ( 0.0004%)
13 4.2141 4.2123 (-0.0004%)
14 4.3762 4.3820 ( 0.0013%)
15 4.5510 4.5458 (-0.0011%)
16 4.6979 4.7043 ( 0.0014%)
17 4.8628 4.8579 (-0.0010%)
18 5.0081 5.0071 (-0.0002%)
19 5.1518 5.1522 ( 0.0001%)
20 5.2906 5.2936 ( 0.0006%)
</pre>
 
=={{header|V (Vlang)}}==
{{trans|Go}}
<syntaxhighlight lang="v (vlang)">import rand
import math
 
const nmax = 20
fn main() {
println(" N average analytical (error)")
println("=== ========= ============ =========")
for n := 1; n <= nmax; n++ {
a := avg(n)
b := ana(n)
println("${n:3} ${a:9.4f} ${b:12.4f} (${math.abs(a-b)/b*100:6.2f}%)" )
}
}
fn avg(n int) f64 {
tests := int(1e4)
mut sum := 0
for _ in 0..tests {
mut v := [nmax]bool{}
for x := 0; !v[x]; {
v[x] = true
sum++
x = rand.intn(n) or {0}
}
}
return f64(sum) / tests
}
fn ana(n int) f64 {
nn := f64(n)
mut term := 1.0
mut sum := 1.0
for i := nn - 1; i >= 1; i-- {
term *= i / nn
sum += term
}
return sum
}</syntaxhighlight>
 
{{out}}
Sample output:
<pre>
N average analytical (error)
=== ========= ============ =========
1 1.0000 1.0000 ( 0.00%)
2 1.4967 1.5000 ( 0.22%)
3 1.8970 1.8889 ( 0.43%)
4 2.2151 2.2188 ( 0.16%)
5 2.5044 2.5104 ( 0.24%)
6 2.7884 2.7747 ( 0.49%)
7 3.0356 3.0181 ( 0.58%)
8 3.2468 3.2450 ( 0.05%)
9 3.4692 3.4583 ( 0.31%)
10 3.6538 3.6602 ( 0.18%)
11 3.8325 3.8524 ( 0.52%)
12 4.0674 4.0361 ( 0.78%)
13 4.2199 4.2123 ( 0.18%)
14 4.3808 4.3820 ( 0.03%)
15 4.5397 4.5458 ( 0.13%)
16 4.6880 4.7043 ( 0.35%)
17 4.8554 4.8579 ( 0.05%)
18 5.0311 5.0071 ( 0.48%)
19 5.1577 5.1522 ( 0.11%)
20 5.2995 5.2936 ( 0.11%)
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "random" for Random
import "./fmt" for Fmt
 
var nmax = 20
var rand = Random.new()
 
var avg = Fn.new { |n|
var tests = 1e4
var sum = 0
for (t in 0...tests) {
var v = List.filled(nmax, false)
var x = 0
while (!v[x]) {
v[x] = true
sum = sum + 1
x = rand.int(n)
}
}
return sum/tests
}
 
var ana = Fn.new { |n|
if (n < 2) return 1
var term = 1
var sum = 1
for (i in n-1..1) {
term = term * i / n
sum = sum + term
}
return sum
}
 
System.print(" N average analytical (error)")
System.print("=== ========= ============ =========")
for (n in 1..nmax) {
var a = avg.call(n)
var b = ana.call(n)
var e = (a - b).abs/ b * 100
Fmt.print("$3d $9.4f $12.4f ($6.2f\%)", n, a, b, e)
}</syntaxhighlight>
 
{{out}}
Sample output:
<pre>
N average analytical (error)
=== ========= ============ =========
1 1.0000 1.0000 ( 0.00%)
2 1.4967 1.5000 ( 0.22%)
3 1.8970 1.8889 ( 0.43%)
4 2.2151 2.2188 ( 0.16%)
5 2.5044 2.5104 ( 0.24%)
6 2.7884 2.7747 ( 0.49%)
7 3.0356 3.0181 ( 0.58%)
8 3.2468 3.2450 ( 0.05%)
9 3.4692 3.4583 ( 0.31%)
10 3.6538 3.6602 ( 0.18%)
11 3.8325 3.8524 ( 0.52%)
12 4.0674 4.0361 ( 0.78%)
13 4.2199 4.2123 ( 0.18%)
14 4.3808 4.3820 ( 0.03%)
15 4.5397 4.5458 ( 0.13%)
16 4.6880 4.7043 ( 0.35%)
17 4.8554 4.8579 ( 0.05%)
18 5.0311 5.0071 ( 0.48%)
19 5.1577 5.1522 ( 0.11%)
20 5.2995 5.2936 ( 0.11%)
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">const N=20;
 
(" N average analytical (error)").println();
Line 2,790 ⟶ 3,722:
n=n.toFloat();
(1).reduce(n,'wrap(sum,i){ sum+fact(n)/n.pow(i)/fact(n-i) },0.0);
}</langsyntaxhighlight>
{{out}}
<pre>
1,995

edits