Given a random number generator, (rng), generating numbers in the range 0.0 .. 1.0 called rgen, for example; and a function modifier(x)
taking an number in the same range and generating the probability that the input should be generated, in the same range 0..1; then implement the following algorithm for generating random numbers to the probability given by function modifier:

while True:
    random1 = rgen()
    random2 = rgen()
    if random2 < modifier(random1):
        answer = random1
        break
    endif
endwhile
Task

 Create a modifier function that generates a 'V' shaped probability of number generation using something like, for example:
                      modifier(x)  =  2*(0.5 - x)  if x < 0.5  else 2*(x - 0.5) 

 Create a generator of random numbers with probabilities modified by the above function.
 Generate >= 10,000 random numbers subject to the probability modification.
 Output a textual histogram with from 11 to 21 bins showing the distribution of the random numbers generated.


Show your output here, on this page.




with Ada.Text_Io;
with Ada.Numerics.Float_Random;
with Ada.Strings.Fixed;
 
procedure Modified_Distribution is
 
   Observations : constant := 20_000;
   Buckets      : constant := 25;
   Divider      : constant := 12;
   Char         : constant Character := '*';
 
   generic
      with function Modifier (X : Float) return Float;
   package Generic_Random is
      function Random return Float;
   end Generic_Random;
 
   package body Generic_Random is
      package Float_Random renames Ada.Numerics.Float_Random;
      Generator : Float_Random.Generator;
 
      function Random return Float is
         Random_1 : Float;
         Random_2 : Float;
      begin
         loop
            Random_1 := Float_Random.Random (Generator);
            Random_2 := Float_Random.Random (Generator);
            if Random_2 < Modifier (Random_1) then
               return Random_1;
            end if;
         end loop;
      end Random;
 
   begin
     Float_Random.Reset (Generator);
   end Generic_Random;
 
   generic
      Buckets : in Positive;
   package Histograms is
      type Bucket_Index is new Positive range 1 .. Buckets;
      Bucket_Width : constant Float := 1.0 / Float (Buckets);
      procedure Clean;
      procedure Increment_Bucket (Observation : Float);
      function Observations_In (Bucket : Bucket_Index) return Natural;
      function To_Bucket (X : Float) return Bucket_Index;
      function Range_Image (Bucket : Bucket_Index) return String;
   end Histograms;
 
   package body Histograms is
      Hist : array (Bucket_Index) of Natural := (others => 0);
 
      procedure Clean is
      begin
         Hist := (others => 0);
      end Clean;
 
      procedure Increment_Bucket (Observation : Float) is
         Bin : constant Bucket_Index := To_Bucket (Observation);
      begin
         Hist (Bin) := Hist (Bin) + 1;
      end Increment_Bucket;
 
      function Observations_In (Bucket : Bucket_Index) return Natural
      is (Hist (Bucket));
 
      function To_Bucket (X : Float) return Bucket_Index
      is (1 + Bucket_Index'Base (Float'Floor (X / Bucket_Width)));
 
      function Range_Image (Bucket : Bucket_Index) return String is
         package Float_Io is new Ada.Text_Io.Float_Io (Float);
         Image : String := "F.FF..L.LL";
         First : constant Float := Float (Bucket - 1) / Float (Buckets);
         Last  : constant Float := Float (Bucket - 1 + 1) / Float (Buckets);
      begin
         Float_Io.Put (Image (1 .. 4),  First, Exp => 0, Aft => 2);
         Float_Io.Put (Image (7 .. 10), Last,  Exp => 0, Aft => 2);
         return Image;
      end Range_Image;
 
   begin
      Clean;
   end Histograms;
 
   function Modifier (X : Float) return Float
   is (if X in Float'First .. 0.5
       then 2.0 * (0.5 - X)
       else 2.0 * (X - 0.5));
 
   package Modified_Random is
     new Generic_Random (Modifier => Modifier);
 
   package Histogram_20 is
     new Histograms (Buckets => Buckets);
 
   function Column (Height : Natural; Char : Character) return String
     renames Ada.Strings.Fixed."*";
 
   use Ada.Text_Io;
begin
   for N in 1 .. Observations loop
      Histogram_20.Increment_Bucket (Modified_Random.Random);
   end loop;
 
   Put ("Range      Observations: "); Put (Observations'Image);
   Put ("  Buckets: "); Put (Buckets'Image);
   New_Line;
   for I in Histogram_20.Bucket_Index'Range loop
      Put (Histogram_20.Range_Image (I));
      Put (" ");
      Put (Column (Histogram_20.Observations_In (I) / Divider, Char));
      New_Line;
   end loop;
end Modified_Distribution;