116 lines
3.6 KiB
Ada
116 lines
3.6 KiB
Ada
with Ada.Text_IO;
|
|
with Ada.Containers.Generic_Array_Sort;
|
|
|
|
procedure EKG_Sequences is
|
|
|
|
type Element_Type is new Integer;
|
|
|
|
type Index_Type is new Integer range 1 .. 100;
|
|
subtype Show_Range is Index_Type range 1 .. 30;
|
|
|
|
type Sequence is array (Index_Type range <>) of Element_Type;
|
|
subtype EKG_Sequence is Sequence (Index_Type);
|
|
|
|
function GCD (Left, Right : Element_Type) return Integer is
|
|
A : Element_Type := Left;
|
|
B : Element_Type := Right;
|
|
begin
|
|
while A /= B loop
|
|
if A > B
|
|
then A := A - B;
|
|
else B := B - A;
|
|
end if;
|
|
end loop;
|
|
return Integer (A);
|
|
end GCD;
|
|
|
|
function Contains (A : Sequence;
|
|
B : Element_Type;
|
|
Last : Index_Type) return Boolean
|
|
is (for some Value of A (A'First .. Last) => Value = B);
|
|
|
|
function Are_Same (S, T : EKG_Sequence; Last : Index_Type) return Boolean is
|
|
S_Copy : Sequence := S (S'First .. Last);
|
|
T_Copy : Sequence := T (T'First .. Last);
|
|
procedure Sort is
|
|
new Ada.Containers.Generic_Array_Sort (Index_Type => Index_Type,
|
|
Element_Type => Element_Type,
|
|
Array_Type => Sequence);
|
|
begin
|
|
Sort (S_Copy);
|
|
Sort (T_Copy);
|
|
return S_Copy = T_Copy;
|
|
end Are_Same;
|
|
|
|
function Create_EKG (Start : Element_Type) return EKG_Sequence is
|
|
EKG : EKG_Sequence := (1 => 1, 2 => Start, others => 0);
|
|
begin
|
|
for N in 3 .. Index_Type'Last loop
|
|
for I in 2 .. Element_Type'Last loop
|
|
-- A potential sequence member cannot already have been used
|
|
-- and must have a factor in common with previous member
|
|
if not Contains (EKG, I, N)
|
|
and then GCD (EKG (N - 1), I) > 1
|
|
then
|
|
EKG (N) := I;
|
|
exit;
|
|
end if;
|
|
end loop;
|
|
end loop;
|
|
return EKG;
|
|
end Create_EKG;
|
|
|
|
procedure Converge (Seq_A, Seq_B : Sequence;
|
|
Term : out Index_Type;
|
|
Do_Converge : out Boolean) is
|
|
begin
|
|
for I in 3 .. Index_Type'Last loop
|
|
if Seq_A (I) = Seq_B (I) and then Are_Same (Seq_A, Seq_B, I) then
|
|
Do_Converge := True;
|
|
Term := I;
|
|
return;
|
|
end if;
|
|
end loop;
|
|
Do_Converge := False;
|
|
Term := Index_Type'Last;
|
|
end Converge;
|
|
|
|
procedure Put (Seq : Sequence) is
|
|
use Ada.Text_IO;
|
|
begin
|
|
Put ("[");
|
|
for E of Seq (Show_Range) loop
|
|
Put (E'Image);
|
|
end loop;
|
|
Put ("]");
|
|
end Put;
|
|
|
|
use Ada.Text_IO;
|
|
EKG_2 : constant EKG_Sequence := Create_EKG (2);
|
|
EKG_5 : constant EKG_Sequence := Create_EKG (5);
|
|
EKG_7 : constant EKG_Sequence := Create_EKG (7);
|
|
EKG_9 : constant EKG_Sequence := Create_EKG (9);
|
|
EKG_10 : constant EKG_Sequence := Create_EKG (10);
|
|
begin
|
|
Put ("EKG( 2): "); Put (EKG_2); New_Line;
|
|
Put ("EKG( 5): "); Put (EKG_5); New_Line;
|
|
Put ("EKG( 7): "); Put (EKG_7); New_Line;
|
|
Put ("EKG( 9): "); Put (EKG_9); New_Line;
|
|
Put ("EKG(10): "); Put (EKG_10); New_Line;
|
|
|
|
-- Now compare EKG5 and EKG7 for convergence
|
|
declare
|
|
Term : Index_Type;
|
|
Do_Converge : Boolean;
|
|
begin
|
|
Converge (EKG_5, EKG_7, Term, Do_Converge);
|
|
New_Line;
|
|
if Do_Converge then
|
|
Put_Line ("EKG(5) and EKG(7) converge at term "
|
|
& Term'Image);
|
|
else
|
|
Put_Line ("EKG5(5) and EKG(7) do not converge within "
|
|
& Term'Image & " terms");
|
|
end if;
|
|
end;
|
|
end EKG_Sequences;
|