Ludic numbers   are related to prime numbers as they are generated by a sieve quite like the Sieve of Eratosthenes is used to generate prime numbers.

The first ludic number is   1.

To generate succeeding ludic numbers create an array of increasing integers starting from   2.

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ...
(Loop)

 Take the first member of the resultant array as the next ludic number   2.
 Remove every   2nd   indexed item from the array (including the first).
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ...
 (Unrolling a few loops...)
 Take the first member of the resultant array as the next ludic number   3.
 Remove every   3rd   indexed item from the array (including the first).
3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 ...
 Take the first member of the resultant array as the next ludic number   5.
 Remove every   5th   indexed item from the array (including the first).
5 7 11 13 17 19 23 25 29 31 35 37 41 43 47 49 53 55 59 61 65 67 71 73 77 ...
 Take the first member of the resultant array as the next ludic number   7.
 Remove every   7th   indexed item from the array (including the first).
7 11 13 17 23 25 29 31 37 41 43 47 53 55 59 61 67 71 73 77 83 85 89 91 97 ...
  ... 
 Take the first member of the current array as the next ludic number   L.
 Remove every   Lth   indexed item from the array (including the first).
  ... 


Task

 Generate and show here the first 25 ludic numbers.
 How many ludic numbers are there less than or equal to 1000?
 Show the 2000..2005th ludic numbers.


Stretch goal

Show all triplets of ludic numbers < 250.

 A triplet is any three numbers     



x
,


{\displaystyle x,}

   



x
+
2
,


{\displaystyle x+2,}

   



x
+
6


{\displaystyle x+6}

      where all three numbers are also ludic numbers. 


with Ada.Text_IO;
with Ada.Containers.Vectors;
 
procedure Ludic_Numbers is
 
   package Lucid_Lists is
      new Ada.Containers.Vectors (Positive, Natural);
   use Lucid_Lists;
 
   List : Vector;
 
   procedure Fill is
      use type Ada.Containers.Count_Type;
      Vec   : Vector;
      Lucid : Natural;
      Index : Positive;
   begin
      Append (List, 1);
 
      for I in 2 .. 22_000 loop
         Append (Vec, I);
      end loop;
 
      loop
         Lucid := First_Element (Vec);
         Append (List, Lucid);
 
         Index := First_Index (Vec);
         loop
            Delete (Vec, Index);
            Index := Index + Lucid - 1;
            exit when Index > Last_Index (Vec);
         end loop;
 
         exit when Length (Vec) <= 1;
      end loop;
 
   end Fill;
 
   procedure Put_Lucid (First, Last : in Natural) is
      use Ada.Text_IO;
   begin
      Put_Line ("Lucid numbers " & First'Image & " to " & Last'Image & ":");
      for I in First .. Last loop
         Put (Natural'(List (I))'Image);
      end loop;
      New_Line;
   end Put_Lucid;
 
   procedure Count_Lucid (Below : in Natural) is
      Count : Natural := 0;
   begin
      for Lucid of List loop
         if Lucid <= Below then
            Count := Count + 1;
         end if;
      end loop;
      Ada.Text_IO.Put_Line ("There are " & Count'Image & " lucid numbers <=" & Below'Image);
   end Count_Lucid;
 
   procedure Find_Triplets (Limit : in Natural) is
 
      function Is_Lucid (Value : in Natural) return Boolean is
      begin
         for X in 1 .. Limit loop
            if List (X) = Value then
               return True;
            end if;
         end loop;
         return False;
      end Is_Lucid;
 
      use Ada.Text_IO;
      Index : Natural;
      Lucid : Natural;
   begin
      Put_Line ("All triplets of lucid numbers <" & Limit'Image);
      Index := First_Index (List);
      while List (Index) < Limit loop
         Lucid := List (Index);
         if Is_Lucid (Lucid + 2) and Is_Lucid (Lucid + 6) then
            Put ("(");
            Put (Lucid'Image);
            Put (Natural'(Lucid + 2)'Image);
            Put (Natural'(Lucid + 6)'Image);
            Put_Line (")");
         end if;
         Index := Index + 1;
      end loop;
   end Find_Triplets;
 
begin
   Fill;
   Put_Lucid (First => 1,
              Last  => 25);
   Count_Lucid (Below => 1000);
   Put_Lucid (First => 2000,
              Last  => 2005);
   Find_Triplets (Limit => 250);
end Ludic_Numbers;