How to resolve the algorithm Average loop length step by step in the Ada programming language
Published on 12 May 2024 09:40 PM
How to resolve the algorithm Average loop length step by step in the Ada programming language
Table of Contents
Problem Statement
Let f be a uniformly-randomly chosen mapping from the numbers 1..N to the numbers 1..N (note: not necessarily a permutation of 1..N; the mapping could produce a number in more than one way or not at all). At some point, the sequence 1, f(1), f(f(1))... will contain a repetition, a number that occurring for the second time in the sequence.
Write a program or a script that estimates, for each N, the average length until the first such repetition. Also calculate this expected length using an analytical formula, and optionally compare the simulated result with the theoretical one.
This problem comes from the end of Donald Knuth's Christmas tree lecture 2011. Example of expected output:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Average loop length step by step in the Ada programming language
Source code in the ada programming language
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;
with Ada.Numerics.Discrete_Random;
procedure Avglen is
package IIO is new Ada.Text_IO.Integer_IO (Positive); use IIO;
package LFIO is new Ada.Text_IO.Float_IO (Long_Float); use LFIO;
subtype FactN is Natural range 0..20;
TESTS : constant Natural := 1_000_000;
function Factorial (N : FactN) return Long_Float is
Result : Long_Float := 1.0;
begin
for I in 2..N loop Result := Result * Long_Float(I); end loop;
return Result;
end Factorial;
function Analytical (N : FactN) return Long_Float is
Sum : Long_Float := 0.0;
begin
for I in 1..N loop
Sum := Sum + Factorial(N) / Factorial(N - I) / Long_Float(N)**I;
end loop;
return Sum;
end Analytical;
function Experimental (N : FactN) return Long_Float is
subtype RandInt is Natural range 1..N;
package Random is new Ada.Numerics.Discrete_Random(RandInt);
seed : Random.Generator;
Num : RandInt;
count : Natural := 0;
bits : array(RandInt'Range) of Boolean;
begin
Random.Reset(seed);
for run in 1..TESTS loop
bits := (others => false);
for I in RandInt'Range loop
Num := Random.Random(seed); exit when bits(Num);
bits(Num) := True; count := count + 1;
end loop;
end loop;
return Long_Float(count)/Long_Float(TESTS);
end Experimental;
A, E, err : Long_Float;
begin
Put_Line(" N avg calc %diff");
for I in 1..20 loop
A := Analytical(I); E := Experimental(I); err := abs(E-A)/A*100.0;
Put(I, Width=>2); Put(E ,Aft=>4, exp=>0); Put(A, Aft=>4, exp=>0);
Put(err, Fore=>3, Aft=>3, exp=>0); New_line;
end loop;
end Avglen;
You may also check:How to resolve the algorithm Bioinformatics/base count step by step in the ARM Assembly programming language
You may also check:How to resolve the algorithm Loops/Continue step by step in the Phix programming language
You may also check:How to resolve the algorithm Verify distribution uniformity/Chi-squared test step by step in the Tcl programming language
You may also check:How to resolve the algorithm Arithmetic/Integer step by step in the ReScript programming language
You may also check:How to resolve the algorithm Miller–Rabin primality test step by step in the Standard ML programming language