Task: EKG sequence convergence





Java: import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class EKGSequenceConvergence {

    public static void main(String[] args) {
        System.out.println("Calculate and show here the first 10 members of EKG[2], EKG[5], EKG[7], EKG[9] and EKG[10].");
        for ( int i : new int[] {2, 5, 7, 9, 10} ) {
            System.out.printf("EKG[%d] = %s%n", i, ekg(i, 10));
        }
        System.out.println("Calculate and show here at which term EKG[5] and EKG[7] converge.");
        List<Integer> ekg5 = ekg(5, 100);
        List<Integer> ekg7 = ekg(7, 100);
        for ( int i = 1 ; i < ekg5.size() ; i++ ) {
            if ( ekg5.get(i) == ekg7.get(i) && sameSeq(ekg5, ekg7, i)) {
                System.out.printf("EKG[%d](%d) = EKG[%d](%d) = %d, and are identical from this term on%n", 5, i+1, 7, i+1, ekg5.get(i));
                break;
            }
        }
    }
    
    
    private static boolean sameSeq(List<Integer> seq1, List<Integer> seq2, int n) {
        List<Integer> list1 = new ArrayList<>(seq1.subList(0, n));
        Collections.sort(list1);
        List<Integer> list2 = new ArrayList<>(seq2.subList(0, n));
        Collections.sort(list2);
        for ( int i = 0 ; i < n ; i++ ) {
            if ( list1.get(i) != list2.get(i) ) {
                return false;
            }
        }
        return true;
    }
    
    
    
    
    private static List<Integer> ekg(int two, int maxN) {
        List<Integer> result = new ArrayList<>();
        result.add(1);
        result.add(two);
        Map<Integer,Integer> seen = new HashMap<>();
        seen.put(1, 1);
        seen.put(two, 1);
        int minUnseen = two == 2 ? 3 : 2;
        int prev = two;
        for ( int n = 3 ; n <= maxN ; n++ ) {
            int test = minUnseen - 1;
            while ( true ) {
                test++;
                if ( ! seen.containsKey(test) && gcd(test, prev) > 1 ) {
                    
                    result.add(test);
                    seen.put(test, n);
                    prev = test;
                    if ( minUnseen == test ) {
                        do {
                            minUnseen++;
                        } while ( seen.containsKey(minUnseen) );
                    }
                    break;
                }
            }
        }
        return result;
    }

    private static final int gcd(int a, int b) {
        if ( b == 0 ) {
            return a;
        }
        return gcd(b, a%b);
    }
        
}







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
            
            
            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;

   
   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;