How to resolve the algorithm Generator/Exponential step by step in the Ada programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Generator/Exponential step by step in the Ada programming language

Table of Contents

Problem Statement

A generator is an executable entity (like a function or procedure) that contains code that yields a sequence of values, one at a time, so that each time you call the generator, the next value in the sequence is provided. Generators are often built on top of coroutines or objects so that the internal state of the object is handled “naturally”. Generators are often used in situations where a sequence is potentially infinite, and where it is possible to construct the next value of the sequence with only minimal state.

Note that this task requires the use of generators in the calculation of the result.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Generator/Exponential step by step in the Ada programming language

Source code in the ada programming language

package Generator is

   type Generator is tagged private;
   procedure Reset (Gen : in out Generator);
   function Get_Next (Gen : access Generator) return Natural;

   type Generator_Function is access function (X : Natural) return Natural;
   procedure Set_Generator_Function (Gen  : in out Generator;
                                     Func : Generator_Function);

   procedure Skip (Gen : access Generator'Class; Count : Positive := 1);

private

   function Identity (X : Natural) return Natural;

   type Generator is tagged record
      Last_Source : Natural := 0;
      Last_Value  : Natural := 0;
      Gen_Func    : Generator_Function := Identity'Access;
   end record;

end Generator;


package Generator.Filtered is

   type Filtered_Generator is new Generator with private;
   procedure Reset (Gen : in out Filtered_Generator);
   function Get_Next (Gen : access Filtered_Generator) return Natural;

   procedure Set_Source (Gen    : in out Filtered_Generator;
                         Source : access Generator);
   procedure Set_Filter (Gen    : in out Filtered_Generator;
                         Filter : access Generator);

private

   type Filtered_Generator is new Generator with record
      Last_Filter : Natural := 0;
      Source, Filter : access Generator;
   end record;

end Generator.Filtered;


package body Generator is

   --------------
   -- Identity --
   --------------

   function Identity (X : Natural) return Natural is
   begin
      return X;
   end Identity;

   ----------
   -- Skip --
   ----------

   procedure Skip (Gen : access Generator'Class; Count : Positive := 1) is
      Val : Natural;
      pragma Unreferenced (Val);
   begin
      for I in 1 .. Count loop
         Val := Gen.Get_Next;
      end loop;
   end Skip;

   -----------
   -- Reset --
   -----------

   procedure Reset (Gen : in out Generator) is
   begin
      Gen.Last_Source := 0;
      Gen.Last_Value := 0;
   end Reset;

   --------------
   -- Get_Next --
   --------------

   function Get_Next (Gen : access Generator) return Natural is
   begin
      Gen.Last_Source := Gen.Last_Source + 1;
      Gen.Last_Value := Gen.Gen_Func (Gen.Last_Source);
      return Gen.Last_Value;
   end Get_Next;

   ----------------------------
   -- Set_Generator_Function --
   ----------------------------

   procedure Set_Generator_Function
     (Gen  : in out Generator;
      Func : Generator_Function)
   is
   begin
      if Func = null then
         Gen.Gen_Func := Identity'Access;
      else
         Gen.Gen_Func := Func;
      end if;
   end Set_Generator_Function;

end Generator;


package body Generator.Filtered is

   -----------
   -- Reset --
   -----------

   procedure Reset (Gen : in out Filtered_Generator) is
   begin
      Reset (Generator (Gen));
      Gen.Source.Reset;
      Gen.Filter.Reset;
      Gen.Last_Filter := 0;
   end Reset;

   --------------
   -- Get_Next --
   --------------

   function Get_Next (Gen : access Filtered_Generator) return Natural is
      Next_Source : Natural := Gen.Source.Get_Next;
      Next_Filter : Natural := Gen.Last_Filter;
   begin
      loop
         if Next_Source > Next_Filter then
            Gen.Last_Filter := Gen.Filter.Get_Next;
            Next_Filter := Gen.Last_Filter;
         elsif Next_Source = Next_Filter then
            Next_Source := Gen.Source.Get_Next;
         else
            return Next_Source;
         end if;
      end loop;
   end Get_Next;

   ----------------
   -- Set_Source --
   ----------------

   procedure Set_Source
     (Gen    : in out Filtered_Generator;
      Source : access Generator)
   is
   begin
      Gen.Source := Source;
   end Set_Source;

   ----------------
   -- Set_Filter --
   ----------------

   procedure Set_Filter
     (Gen    : in out Filtered_Generator;
      Filter : access Generator)
   is
   begin
      Gen.Filter := Filter;
   end Set_Filter;

end Generator.Filtered;


with Ada.Text_IO;
with Generator.Filtered;

procedure Generator_Test is

   function Square (X : Natural) return Natural is
   begin
      return X * X;
   end Square;

   function Cube (X : Natural) return Natural is
   begin
      return X * X * X;
   end Cube;

   G1, G2 : aliased Generator.Generator;
   F : aliased Generator.Filtered.Filtered_Generator;

begin

   G1.Set_Generator_Function (Func => Square'Unrestricted_Access);
   G2.Set_Generator_Function (Func => Cube'Unrestricted_Access);

   F.Set_Source (G1'Unrestricted_Access);
   F.Set_Filter (G2'Unrestricted_Access);

   F.Skip (20);

   for I in 1 .. 10 loop
      Ada.Text_IO.Put ("I:" & Integer'Image (I));
      Ada.Text_IO.Put (", F:" & Integer'Image (F.Get_Next));
      Ada.Text_IO.New_Line;
   end loop;

end Generator_Test;


  

You may also check:How to resolve the algorithm Collections step by step in the MiniScript programming language
You may also check:How to resolve the algorithm Shell one-liner step by step in the Objeck programming language
You may also check:How to resolve the algorithm One-dimensional cellular automata step by step in the Mathematica / Wolfram Language programming language
You may also check:How to resolve the algorithm Steffensen's method step by step in the Julia programming language
You may also check:How to resolve the algorithm Largest number divisible by its digits step by step in the C++ programming language