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