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. 


DEFINE NOTLUDIC="0"
DEFINE LUDIC="1"
DEFINE UNKNOWN="2"
 
PROC LudicSieve(BYTE ARRAY a INT count)
  INT i,j,k
 
  SetBlock(a,count,UNKNOWN)
  a(0)=NOTLUDIC
  a(1)=LUDIC
 
  i=2
  WHILE i<count
  DO
    IF a(i)=UNKNOWN THEN
      a(i)=LUDIC
      j=i k=0
      WHILE j<count
      DO
        IF a(j)=UNKNOWN THEN
          k==+1
          IF k=i THEN
            a(j)=NOTLUDIC
            k=0
          FI
        FI
        j==+1
      OD
    FI
    i==+1
    Poke(77,0) ;turn off the attract mode
  OD
RETURN
 
PROC PrintLudicNumbers(BYTE ARRAY a INT count,first,last)
  INT i,j
 
  i=1 j=0
  WHILE i<count AND j<=last
  DO
    IF a(i)=LUDIC THEN
      IF j>=first THEN
        PrintI(i) Put(32)
      FI
      j==+1
    FI
    i==+1
  OD
  PutE() PutE()
RETURN
 
INT FUNC CountLudicNumbers(BYTE ARRAY a INT max)
  INT i,res
 
  res=0
  FOR i=1 TO max
  DO
    IF a(i)=LUDIC THEN
      res==+1
    FI
  OD
RETURN (res)
 
PROC PrintLudicTriplets(BYTE ARRAY a INT max)
  INT i,j
 
  j=0
  FOR i=0 TO max-6
  DO
    IF a(i)=LUDIC AND a(i+2)=LUDIC AND a(i+6)=LUDIC THEN
      j==+1
      PrintF("%I. %I-%I-%I%E",j,i,i+2,i+6)
    FI
  OD
RETURN
 
PROC Main()
  DEFINE COUNT="22000"
  BYTE ARRAY lud(COUNT+1)
  INT i,n
 
  PrintE("Please wait...")
  LudicSieve(lud,COUNT+1)
  Put(125) PutE() ;clear the screen
 
  PrintE("First 25 ludic numbers:")
  PrintLudicNumbers(lud,COUNT+1,0,24)
 
  n=CountLudicNumbers(lud,1000)
  PrintF("There are %I ludic numbers <= 1000%E%E",n)
 
  PrintE("2000'th..2005'th ludic numbers:")
  PrintLudicNumbers(lud,COUNT+1,1999,2004)
 
  PrintE("Ludic triplets below 250")
  PrintLudicTriplets(lud,249)
RETURN