This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,12 @@
generic
Sample_Size: Positive;
type Item_Type is private;
package S_Of_N_Creator is
subtype Index_Type is Positive range 1 .. Sample_Size;
type Item_Array is array (Index_Type) of Item_Type;
procedure Update(New_Item: Item_Type);
function Result return Item_Array;
end S_Of_N_Creator;

View file

@ -0,0 +1,38 @@
with Ada.Numerics.Float_Random, Ada.Numerics.Discrete_Random;
package body S_Of_N_Creator is
package F_Rnd renames Ada.Numerics.Float_Random;
F_Gen: F_Rnd.Generator;
package D_Rnd is new Ada.Numerics.Discrete_Random(Index_Type);
D_Gen: D_Rnd.Generator;
Item_Count: Natural := 0; -- this is a global counter
Sample: Item_Array; -- also used globally
procedure Update(New_Item: Item_Type) is
begin
Item_Count := Item_Count + 1;
if Item_Count <= Sample_Size then
-- select the first Sample_Size items as the sample
Sample(Item_Count) := New_Item;
else
-- for I-th item, I > Sample_Size: Sample_Size/I chance of keeping it
if (Float(Sample_Size)/Float(Item_Count)) > F_Rnd.Random(F_Gen) then
-- randomly (1/Sample_Size) replace one of the items of the sample
Sample(D_Rnd.Random(D_Gen)) := New_Item;
end if;
end if;
end Update;
function Result return Item_Array is
begin
Item_Count := 0; -- ready to start another run
return Sample;
end Result;
begin
D_Rnd.Reset(D_Gen); -- at package instantiation, initialize rnd-generators
F_Rnd.Reset(F_Gen);
end S_Of_N_Creator;

View file

@ -0,0 +1,34 @@
with S_Of_N_Creator, Ada.Text_IO;
procedure Test_S_Of_N is
Repetitions: constant Positive := 100_000;
type D_10 is range 0 .. 9;
-- the instantiation of the generic package S_Of_N_Creator generates
-- a package with the desired functionality
package S_Of_3 is new S_Of_N_Creator(Sample_Size => 3, Item_Type => D_10);
Sample: S_Of_3.Item_Array;
Result: array(D_10) of Natural := (others => 0);
begin
for J in 1 .. Repetitions loop
-- get Sample
for Dig in D_10 loop
S_Of_3.Update(Dig);
end loop;
Sample := S_Of_3.Result;
-- update current Result
for Item in Sample'Range loop
Result(Sample(Item)) := Result(Sample(Item)) + 1;
end loop;
end loop;
-- finally: output Result
for Dig in Result'Range loop
Ada.Text_IO.Put(D_10'Image(Dig) & ":"
& Natural'Image(Result(Dig)) & "; ");
end loop;
end Test_S_Of_N;