Ludic numbers

From Rosetta Code
Task
Ludic numbers
You are encouraged to solve this task according to the task description, using any language you may know.

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             where all three numbers are also ludic numbers.



11l

Translation of: Python
F ludic(nmax = 100000)
   V r = [1]
   V lst = Array(2..nmax)
   L !lst.empty
      r.append(lst[0])
      [Int] newlst
      V step = lst[0]
      L(i) 0 .< lst.len
         I i % step != 0
            newlst.append(lst[i])
      lst = newlst
   R r

V ludics = ludic()
print(‘First 25 ludic primes:’)
print(ludics[0.<25])
print("\nThere are #. ludic numbers <= 1000".format(sum(ludics.filter(l -> l <= 1000).map(l -> 1))))
print("\n2000'th..2005'th ludic primes:")
print(ludics[2000 - 1 .. 2004])
V n = 250
V triplets = ludics.filter(x -> x + 6 < :n &
                           x + 2 C :ludics &
                           x + 6 C :ludics).map(x -> (x, x + 2, x + 6))
print("\nThere are #. triplets less than #.:\n  #.".format(triplets.len, n, triplets))
Output:
First 25 ludic primes:
[1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107]

There are 142 ludic numbers <= 1000

2000'th..2005'th ludic primes:
[21475, 21481, 21487, 21493, 21503, 21511]

There are 8 triplets less than 250:
  [(1, 3, 7), (5, 7, 11), (11, 13, 17), (23, 25, 29), (41, 43, 47), (173, 175, 179), (221, 223, 227), (233, 235, 239)]

360 Assembly

Translation of: Fortran
*        Ludic numbers             23/04/2016
LUDICN   CSECT
         USING  LUDICN,R15         set base register
         LH     R9,NMAX            r9=nmax
         SRA    R9,1               r9=nmax/2
         LA     R6,2               i=2
LOOPI1   CR     R6,R9              do i=2 to nmax/2
         BH     ELOOPI1
         LA     R1,LUDIC-1(R6)     @ludic(i)
         CLI    0(R1),X'01'        if ludic(i)
         BNE    ELOOPJ1
         SR     R8,R8              n=0
         LA     R7,1(R6)           j=i+1
LOOPJ1   CH     R7,NMAX            do j=i+1 to nmax
         BH     ELOOPJ1
         LA     R1,LUDIC-1(R7)     @ludic(j)
         CLI    0(R1),X'01'        if ludic(j)
         BNE    NOTJ1
         LA     R8,1(R8)           n=n+1
NOTJ1    CR     R8,R6              if n=i 
         BNE    NDIFI
         LA     R1,LUDIC-1(R7)     @ludic(j)
         MVI    0(R1),X'00'        ludic(j)=false
         SR     R8,R8              n=0
NDIFI    LA     R7,1(R7)           j=j+1
         B      LOOPJ1
ELOOPJ1  LA     R6,1(R6)           i=i+1
         B      LOOPI1
ELOOPI1  XPRNT  =C'First 25 ludic numbers:',23
         LA     R10,BUF            @buf=0
         SR     R8,R8              n=0
         LA     R6,1               i=1
LOOPI2   CH     R6,NMAX            do i=1 to nmax
         BH     ELOOPI2
         LA     R1,LUDIC-1(R6)     @ludic(i)
         CLI    0(R1),X'01'        if ludic(i)
         BNE    NOTI2
         XDECO  R6,XDEC            i
         MVC    0(4,R10),XDEC+8    output i 
         LA     R10,4(R10)         @buf=@buf+4
         LA     R8,1(R8)           n=n+1
         LR     R2,R8              n
         SRDA   R2,32
         D      R2,=F'5'           r2=mod(n,5)
         LTR    R2,R2              if mod(n,5)=0
         BNZ    NOTI2
         XPRNT  BUF,20
         LA     R10,BUF            @buf=0
NOTI2    EQU    *
         CH     R8,=H'25'          if n=25
         BE     ELOOPI2
         LA     R6,1(R6)           i=i+1
         B      LOOPI2
ELOOPI2  MVC    BUF(25),=C'Ludic numbers below 1000:'
         SR     R8,R8              n=0
         LA     R6,1               i=1
LOOPI3   CH     R6,=H'999'         do i=1 to 999
         BH     ELOOPI3
         LA     R1,LUDIC-1(R6)     @ludic(i)
         CLI    0(R1),X'01'        if ludic(i)
         BNE    NOTI3
         LA     R8,1(R8)           n=n+1
NOTI3    LA     R6,1(R6)           i=i+1
         B      LOOPI3
ELOOPI3  XDECO  R8,XDEC            edit n
         MVC    BUF+25(6),XDEC+6   output n
         XPRNT  BUF,31             print buffer
         MVC    BUF(80),=CL80'Ludic numbers 2000 to 2005:'
         LA     R10,BUF+28         @buf=28
         SR     R8,R8              n=0
         LA     R6,1               i=1
LOOPI4   CH     R6,NMAX            do i=1 to nmax
         BH     ELOOPI4
         LA     R1,LUDIC-1(R6)     @ludic(i)
         CLI    0(R1),X'01'        if ludic(i)
         BNE    NOTI4
         LA     R8,1(R8)           n=n+1
         CH     R8,=H'2000'        if n>=2000
         BL     NOTI4
         XDECO  R6,XDEC            edit i
         MVC    0(6,R10),XDEC+6    output i
         LA     R10,6(R10)         @buf=@buf+6
         CH     R8,=H'2005'        if n=2005
         BE     ELOOPI4
NOTI4    LA     R6,1(R6)           i=i+1
         B      LOOPI4
ELOOPI4  XPRNT  BUF,80             print buffer
         XPRNT  =C'Ludic triplets below 250:',25
         LA     R6,1               i=1
LOOPI5   CH     R6,=H'243'         do i=1 to 243
         BH     ELOOPI5
         LA     R1,LUDIC-1(R6)     @ludic(i)
         CLI    0(R1),X'01'        if ludic(i)
         BNE    ITERI5
         LA     R1,LUDIC+1(R6)     @ludic(i+2)
         CLI    0(R1),X'01'        if ludic(i+2)
         BNE    ITERI5
         LA     R1,LUDIC+5(R6)     @ludic(i+6)
         CLI    0(R1),X'01'        if ludic(i+6)
         BNE    ITERI5
         MVC    BUF+0(1),=C'['     [
         XDECO  R6,XDEC            edit i
         MVC    BUF+1(4),XDEC+8    output i
         LA     R2,2(R6)           i+2
         XDECO  R2,XDEC            edit i+2
         MVC    BUF+5(4),XDEC+8    output i+2
         LA     R2,6(R6)           i+6
         XDECO  R2,XDEC            edit i+6
         MVC    BUF+9(4),XDEC+8    output i+6
         MVC    BUF+13(1),=C']'    ]
         XPRNT  BUF,14             print buffer
ITERI5   LA     R6,1(R6)           i=i+1
         B      LOOPI5
ELOOPI5  XR     R15,R15            set return code
         BR     R14                return to caller
         LTORG  
BUF      DS     CL80               buffer
XDEC     DS     CL12               decimal editor
NMAX     DC     H'25000'           nmax
LUDIC    DC     25000X'01'         ludic(nmax)=true
         YREGS
         END    LUDICN
Output:
First 25 ludic numbers:
   1   2   3   5   7
  11  13  17  23  25
  29  37  41  43  47
  53  61  67  71  77
  83  89  91  97 107
Ludic numbers below 1000:   142
Ludic numbers 2000 to 2005:  21475 21481 21487 21493 21503 21511
Ludic triplets below 250:
[   1   3   7]
[   5   7  11]
[  11  13  17]
[  23  25  29]
[  41  43  47]
[ 173 175 179]
[ 221 223 227]
[ 233 235 239]

ABAP

Works with NW 7.40 SP8

CLASS lcl_ludic DEFINITION CREATE PUBLIC.

  PUBLIC SECTION.
    TYPES: t_ludics TYPE SORTED TABLE OF i WITH UNIQUE KEY table_line.
    TYPES: BEGIN OF t_triplet,
             i1 TYPE i,
             i2 TYPE i,
             i3 TYPE i,
           END OF t_triplet.
    TYPES: t_triplets TYPE STANDARD TABLE OF t_triplet WITH EMPTY KEY.

    CLASS-METHODS:
      ludic_up_to
        IMPORTING i_int           TYPE i
        RETURNING VALUE(r_ludics) TYPE t_ludics,
      get_triplets
        IMPORTING i_ludics          TYPE t_ludics
        RETURNING VALUE(r_triplets) TYPE t_triplets.

    "RETURNING parameters (CallByValue) only used for readability of the demo
    "in "Real Life" you should use EXPORTING (CallByRef) for tables

ENDCLASS.

cl_demo_output=>begin_section( 'First 25 Ludics' ).
cl_demo_output=>write( lcl_ludic=>ludic_up_to( 110 ) ).

cl_demo_output=>begin_section( 'Ludics up to 1000' ).
cl_demo_output=>write( lines( lcl_ludic=>ludic_up_to( 1000 ) ) ).

cl_demo_output=>begin_section( '2000th - 2005th Ludics' ).
DATA(ludics) = lcl_ludic=>ludic_up_to( 22000 ).
cl_demo_output=>write( VALUE lcl_ludic=>t_ludics( FOR i = 2000 WHILE i <= 2005 ( ludics[ i ] ) ) ).

cl_demo_output=>begin_section( 'Triplets up to 250' ).
cl_demo_output=>write( lcl_ludic=>get_triplets( lcl_ludic=>ludic_up_to( 250 ) ) ).

cl_demo_output=>display( ).

CLASS lcl_ludic IMPLEMENTATION.

  METHOD ludic_up_to.

    r_ludics = VALUE #( FOR i = 2 WHILE i <= i_int ( i ) ).

    DATA(cursor) = 0.

    WHILE cursor < lines( r_ludics ).

      cursor = cursor + 1.
      DATA(this_ludic) = r_ludics[ cursor ].
      DATA(remove_cursor) = cursor + this_ludic.

      WHILE remove_cursor <= lines( r_ludics ).
        DELETE r_ludics INDEX remove_cursor.
        remove_cursor = remove_cursor + this_ludic - 1.
      ENDWHILE.

    ENDWHILE.

    INSERT 1 INTO TABLE r_ludics.  "add one as the first Ludic number (per definition)

  ENDMETHOD.

  METHOD get_triplets.

    DATA(i) = 0.
    WHILE i < lines( i_ludics ) - 2.
      i = i + 1.

      DATA(this_ludic) = i_ludics[ i ].
      IF  line_exists( i_ludics[ table_line = this_ludic + 2 ] )
      AND line_exists( i_ludics[ table_line = this_ludic + 6 ] ).
        r_triplets = VALUE #(
           BASE r_triplets
           ( i1 = i_ludics[ table_line = this_ludic ]
             i2 = i_ludics[ table_line = this_ludic + 2 ]
             i3 = i_ludics[ table_line = this_ludic + 6 ]
           )
        ).
      ENDIF.

    ENDWHILE.

  ENDMETHOD.

ENDCLASS.
Output:
First 25 Ludics
1 
2 
3 
5 
7 
11 
13 
17 
23 
25 
29 
37 
41 
43 
47 
53 
61 
67 
71 
77 
83 
89 
91 
97 
107 

Ludics up to 1000
142 

2000th - 2005th Ludics
21475 
21481 
21487 
21493 
21503 
21511 

Triplets up to 250
1 3 7 
5 7 11 
11 13 17 
23 25 29 
41 43 47 
173 175 179 
221 223 227 
233 235 239 

Action!

Calculations on a real Atari 8-bit computer take quite long time. It is recommended to use an emulator capable with increasing speed of Atari CPU.

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
Output:

Screenshot from Atari 8-bit computer

First 25 ludic numbers:
1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107

There are 142 ludic numbers <= 1000

2000'th..2005'th ludic numbers:
21475 21481 21487 21493 21503 21511

Ludic triplets below 250
1. 1-3-7
2. 5-7-11
3. 11-13-17
4. 23-25-29
5. 41-43-47
6. 173-175-179
7. 221-223-227
8. 233-235-239

Ada

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;
Output:
Lucid numbers  1 to  25:
 1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107
There are  142 lucid numbers <= 1000
Lucid numbers  2000 to  2005:
 21475 21481 21487 21493 21503 21511
All triplets of lucid numbers < 250
( 1 3 7)
( 5 7 11)
( 11 13 17)
( 23 25 29)
( 41 43 47)
( 173 175 179)
( 221 223 227)
( 233 235 239)

ALGOL 68

# find some Ludic numbers                                #

# sieve the Ludic numbers up to 30 000                   #
INT   max number = 30 000;
[ 1 : max number ]INT candidates;
FOR n TO UPB candidates DO candidates[ n ] := n OD;
FOR n FROM 2 TO UPB candidates OVER 2 DO
    IF candidates[ n ] /= 0 THEN
        # have a ludic number                             #
        INT number count := -1;
        FOR remove pos FROM n TO UPB candidates DO
            IF candidates[ remove pos ] /= 0 THEN
                # have a number we haven't elminated yet  #
                number count +:= 1;
                IF number count = n THEN
                    # this number should be removed       #
                    candidates[ remove pos ] := 0;
                    number count := 0
                FI
            FI
        OD
    FI                
OD;
# show some Ludic numbers and counts                      #
print( ( "Ludic numbers: " ) );
INT ludic count :=  0;
FOR n TO UPB candidates DO
    IF candidates[ n ] /= 0 THEN
        # have a ludic number                             #
        ludic count +:= 1;
        IF ludic count < 26 THEN
            # this is one of the first few Ludic numbers  #
            print( ( " ", whole( n, 0 ) ) );
            IF ludic count = 25 THEN
                print( ( " ...", newline ) )
            FI
        FI;
        IF ludic count = 2000 THEN
            print( ( "Ludic numbers 2000-2005: ", whole( n, 0 ) ) )
        ELIF ludic count > 2000 AND ludic count < 2006 THEN
            print( ( " ", whole( n, 0 ) ) );
            IF ludic count = 2005 THEN
                print( ( newline ) )
            FI
        FI
    FI;
    IF n = 1000 THEN
        # count ludic numbers up to 1000                  #
        print( ( "There are ", whole( ludic count, 0 ), " Ludic numbers up to 1000", newline ) )
    FI
OD;
# find the Ludic triplets below 250                        #
print( ( "Ludic triplets below 250:", newline ) );
FOR n TO 250 - 6 DO
    IF candidates[ n ] /= 0 AND candidates[ n + 2 ] /= 0 AND candidates[ n + 6 ] /= 0 THEN
        # have a triplet                                   #
        print( ( "    ", whole( n, -3 ), ", ", whole( n + 2, -3 ), ", ", whole( n + 6, -3 ), newline ) )
    FI
OD
Output:
Ludic numbers:  1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107 ...
There are 142 Ludic numbers up to 1000
Ludic numbers 2000-2005: 21475 21481 21487 21493 21503 21511
Ludic triplets below 250:
      1,   3,   7
      5,   7,  11
     11,  13,  17
     23,  25,  29
     41,  43,  47
    173, 175, 179
    221, 223, 227
    233, 235, 239

AppleScript

-- Generate a list of the ludic numbers up to and including n.
on ludicsTo(n)
    if (n < 1) then return {}
    -- Start with an array of numbers from 2 to n and a ludic collection already containing 1.
    script o
        property array : {}
        property ludics : {1}
    end script
    repeat with i from 2 to n
        set end of o's array to i
    end repeat
    -- Collect ludics and sieve the array until a ludic matches or exceeds the remaining
    -- array length, at which point the array contains just the remaining ludics.
    set thisLudic to 2
    set arrayLength to n - 1
    repeat while (thisLudic < arrayLength)
        set end of o's ludics to thisLudic
        repeat with i from 1 to arrayLength by thisLudic
            set item i of o's array to missing value
        end repeat
        set o's array to o's array's numbers
        set thisLudic to beginning of o's array
        set arrayLength to (count o's array)
    end repeat
    
    return (o's ludics) & (o's array)
end ludicsTo

on doTask()
    script o
        property ludics : ludicsTo(22000)
    end script
    
    set output to {}
    set astid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to ", "
    set end of output to "First 25 ludic numbers:"
    set end of output to (items 1 thru 25 of o's ludics) as text
    repeat with i from 1 to (count o's ludics)
        if (item i of o's ludics > 1000) then exit repeat
    end repeat
    set end of output to "There are " & (i - 1) & " ludic numbers ≤ 1000."
    set end of output to "2000th-2005th ludic numbers:"
    set end of output to (items 2000 thru 2005 of o's ludics) as text
    set end of output to "Triplets < 250:"
    set triplets to {}
    repeat with x in o's ludics
        set x to x's contents
        if (x > 243) then exit repeat
        if ((x + 2) is in o's ludics) and ((x + 6) is in o's ludics) then
            set end of triplets to "{" & {x, x + 2, x + 6} & "}"
        end if
    end repeat
    set end of output to triplets as text
    set AppleScript's text item delimiters to linefeed
    set output to output as text
    set AppleScript's text item delimiters to astid
    
    return output
end doTask

return doTask()
Output:
"First 25 ludic numbers:
1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107
There are 142 ludic numbers ≤ 1000.
2000th-2005th ludic numbers:
21475, 21481, 21487, 21493, 21503, 21511
Triplets < 250:
{1, 3, 7}, {5, 7, 11}, {11, 13, 17}, {23, 25, 29}, {41, 43, 47}, {173, 175, 179}, {221, 223, 227}, {233, 235, 239}"

Arturo

ludicGen: function [nmax][
    result: [1]
    lst: new 2..nmax+1
    i: 0
    worked: false
    while [and? [not? empty? lst] [i < size lst]][
        item: lst\[i]
        result: result ++ item
        del: 0
        worked: false
        while [del < size lst][
            worked: true
            remove 'lst .index del
            del: dec del + item
        ]
        if not? worked -> i: i + 1
    ]
    return result
]

ludics: ludicGen 25000

print "The first 25 ludic numbers:"
print first.n: 25 ludics

leThan1000: select ludics => [& =< 1000]
print ["\nThere are" size leThan1000 "ludic numbers less than/or equal to 1000\n"]

print ["The ludic numbers from 2000th to 2005th are:" slice ludics 1999 2004 "\n"]

print "The triplets of ludic numbers less than 250 are:"
print map select ludics 'x [
    all? @[ x < 250
            contains? ludics x+2
            contains? ludics x+6
    ]
] 't -> @[t, t+2, t+6]
Output:
The first 25 ludic numbers:
1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107 

There are 142 ludic numbers less than/or equal to 1000
 
The ludic numbers from 2000th to 2005th are: [21475 21481 21487 21493 21503 21511] 
 
The triplets of ludic numbers less than 250 are:
[1 3 7] [5 7 11] [11 13 17] [23 25 29] [41 43 47] [173 175 179] [221 223 227] [233 235 239]

AutoHotkey

Works with: AutoHotkey 1.1
#NoEnv
SetBatchLines, -1
Ludic := LudicSieve(22000)

Loop, 25    ; the first 25 ludic numbers
	Task1 .= Ludic[A_Index] " "

for i, Val in Ludic    ; the number of ludic numbers less than or equal to 1000
	if (Val <= 1000)
		Task2++
	else
		break

Loop, 6    ; the 2000..2005'th ludic numbers
	Task3 .= Ludic[1999 + A_Index] " "

for i, Val in Ludic {    ; all triplets of ludic numbers < 250
	if (Val + 6 > 249)
		break
	if (Ludic[i + 1] = Val + 2 && Ludic[i + 2] = Val + 6 || i = 1)
		Task4 .= "(" Val " " Val + 2 " " Val + 6 ") "
}

MsgBox, % "First 25:`t`t" Task1
	. "`nLudics below 1000:`t" Task2
	. "`nLudic 2000 to 2005:`t" Task3
	. "`nTriples below 250:`t" Task4
return

LudicSieve(Limit) {
	Arr := [], Ludic := []
	Loop, % Limit
		Arr.Insert(A_Index)
	Ludic.Insert(Arr.Remove(1))
	while Arr.MaxIndex() != 1 {
		Ludic.Insert(n := Arr.Remove(1))
		, Removed := 0
		Loop, % Arr.MaxIndex() // n {
			Arr.Remove(A_Index * n - Removed)
			, Removed++
		}
	}
	Ludic.Insert(Arr[1])
	return Ludic
}
Output:
First 25:		1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107 
Ludics below 1000:	142
Ludic 2000 to 2005:	21475 21481 21487 21493 21503 21511 
Triples below 250:	(1 3 7) (5 7 11) (11 13 17) (23 25 29) (41 43 47) (173 175 179) (221 223 227) (233 235 239) 

C

#include <stdio.h>
#include <stdlib.h>

typedef unsigned uint;
typedef struct { uint i, v; } filt_t;

// ludics with at least so many elements and reach at least such value
uint* ludic(uint min_len, uint min_val, uint *len)
{
	uint cap, i, v, active = 1, nf = 0;
	filt_t *f = calloc(cap = 2, sizeof(*f));
	f[1].i = 4;

	for (v = 1; ; ++v) {
		for (i = 1; i < active && --f[i].i; i++);

		if (i < active)
			f[i].i = f[i].v;
		else if (nf == f[i].i)
			f[i].i = f[i].v, ++active;  // enable one more filter
		else {
			if (nf >= cap)
				f = realloc(f, sizeof(*f) * (cap*=2));
			f[nf] = (filt_t){ v + nf, v };
			if (++nf >= min_len && v >= min_val) break;
		}
	}

	// pack the sequence into a uint[]
	// filt_t struct was used earlier for cache locality in loops
	uint *x = (void*) f;
	for (i = 0; i < nf; i++) x[i] = f[i].v;
	x = realloc(x, sizeof(*x) * nf);

	*len = nf;
	return x;
}

int find(uint *a, uint v)
{
	uint i;
	for (i = 0; a[i] <= v; i++)
		if (v == a[i]) return 1;
	return 0;
}

int main(void)
{
	uint len, i, *x = ludic(2005, 1000, &len);

	printf("First 25:");
	for (i = 0; i < 25; i++) printf(" %u", x[i]);
	putchar('\n');

	for (i = 0; x[i] <= 1000; i++);
	printf("Ludics below 1000: %u\n", i);

	printf("Ludic 2000 to 2005:");
	for (i = 2000; i <= 2005; i++) printf(" %u", x[i - 1]);
	putchar('\n');

	printf("Triples below 250:");
	for (i = 0; x[i] + 6 <= 250; i++)
		if (find(x, x[i] + 2) && find(x, x[i] + 6))
			printf(" (%u %u %u)", x[i], x[i] + 2, x[i] + 6);

	putchar('\n');

	free(x);
	return 0;
}
Output:
First 25: 1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107
Ludics below 1000: 142
Ludic 2000 to 2005: 21475 21481 21487 21493 21503 21511
Triples below 250: (1 3 7) (5 7 11) (11 13 17) (23 25 29) (41 43 47) (173 175 179) (221 223 227) (233 235 239)

C#

using System;
using System.Linq;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("First 25 ludic numbers:");
        Console.WriteLine(string.Join(", ", LudicNumbers(150).Take(25)));
        Console.WriteLine();
        
        Console.WriteLine($"There are {LudicNumbers(1001).Count()} ludic numbers below 1000");
        Console.WriteLine();
        
        foreach (var ludic in LudicNumbers(22000).Skip(1999).Take(6)
                .Select((n, i) => $"#{i+2000} = {n}")) {
            Console.WriteLine(ludic);
        }
        Console.WriteLine();
        
        Console.WriteLine("Triplets below 250:");
        var queue = new Queue<int>(5);
        foreach (int x in LudicNumbers(255)) {
            if (queue.Count == 5) queue.Dequeue();
            queue.Enqueue(x);
            if (x - 6 < 250 && queue.Contains(x - 6) && queue.Contains(x - 4)) {
                Console.WriteLine($"{x-6}, {x-4}, {x}");
            }
        }
    }
    
    public static IEnumerable<int> LudicNumbers(int limit) {
        yield return 1;
        //Like a linked list, but with value types.
        //Create 2 extra entries at the start to avoid ugly index calculations
        //and another at the end to avoid checking for index-out-of-bounds.
        Entry[] values = Enumerable.Range(0, limit + 1).Select(n => new Entry(n)).ToArray();
        for (int i = 2; i < limit; i = values[i].Next) {
            yield return values[i].N;
            int start = i;
            while (start < limit) {
                Unlink(values, start);
                for (int step = 0; step < i && start < limit; step++)
                    start = values[start].Next;
            }
        }
    }
    
    static void Unlink(Entry[] values, int index) {
        values[values[index].Prev].Next = values[index].Next;
        values[values[index].Next].Prev = values[index].Prev;
    }
    
}

struct Entry
{
    public Entry(int n) : this() {
        N = n;
        Prev = n - 1;
        Next = n + 1;
    }
    
    public int N { get; }
    public int Prev { get; set; }
    public int Next { get; set; }
}
Output:
First 25 ludic numbers:
1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107

There are 142 ludic numbers below 1000

#2000 = 21475
#2001 = 21481
#2002 = 21487
#2003 = 21493
#2004 = 21503
#2005 = 21511

Triplets below 250:
1, 3, 7
5, 7, 11
11, 13, 17
23, 25, 29
41, 43, 47
173, 175, 179
221, 223, 227
233, 235, 239

C++

#include <vector>
#include <iostream>
using namespace std;

class ludic
{
public:
    void ludicList()
    {
        _list.push_back( 1 );

        vector<int> v;
        for( int x = 2; x < 22000; x++ )
            v.push_back( x );

        while( true )
        {
            vector<int>::iterator i = v.begin();
            int z = *i;
            _list.push_back( z );

            while( true )
            {
                i = v.erase( i );
                if( distance( i, v.end() ) <= z - 1 ) break;
                advance( i, z - 1 );
            }
            if( v.size() < 1 ) return;
        }
    }

    void show( int s, int e )
    {
        for( int x = s; x < e; x++ )
            cout << _list[x] << " ";
    }

    void findTriplets( int e )
    {
        int lu, x = 0;
        while( _list[x] < e )
        {
            lu = _list[x];
            if( inList( lu + 2 ) && inList( lu + 6 ) )
                cout << "(" << lu << " " << lu + 2 << " " << lu + 6 << ")\n";
            x++;
        }
    }

    int count( int e )
    {
        int x = 0, c = 0;
        while( _list[x++] <= 1000 ) c++;
        return c;
    }

private:
    bool inList( int lu )
    {
        for( int x = 0; x < 250; x++ )
            if( _list[x] == lu ) return true;
        return false;
    }

    vector<int> _list;
};

int main( int argc, char* argv[] )
{
    ludic l;
    l.ludicList();
    cout << "first 25 ludic numbers:" << "\n";
    l.show( 0, 25 );
    cout << "\n\nThere are " << l.count( 1000 ) << " ludic numbers <= 1000" << "\n";
    cout << "\n2000 to 2005'th ludic numbers:" << "\n";
    l.show( 1999, 2005 );
    cout << "\n\nall triplets of ludic numbers < 250:" << "\n";
    l.findTriplets( 250 );
    cout << "\n\n";
    return system( "pause" );
}
Output:
first 25 ludic numbers:
1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107

There are 142 ludic numbers <= 1000

2000 to 2005'th ludic numbers:
21475 21481 21487 21493 21503 21511

all triplets of ludic numbers < 250:
(1 3 7)
(5 7 11)
(11 13 17)
(23 25 29)
(41 43 47)
(173 175 179)
(221 223 227)
(233 235 239)

Clojure

(defn ints-from [n]
  (cons n (lazy-seq (ints-from (inc n)))))

(defn drop-nth [n seq] 
   (cond 
      (zero?    n) seq
      (empty? seq) []
      :else (concat (take (dec n) seq) (lazy-seq (drop-nth n (drop n seq))))))

(def ludic ((fn ludic
   ([] (ludic 1))
   ([n] (ludic n (ints-from (inc n))))
   ([n [f & r]] (cons n (lazy-seq (ludic f (drop-nth f r))))))))

(defn ludic? [n]  (= (first (filter (partial <= n) ludic)) n))
   
(print "First 25: ")
(println (take 25 ludic))
(print "Count below 1000: ")
(println (count (take-while (partial > 1000) ludic)))
(print "2000th through 2005th: ")
(println (map (partial nth ludic) (range 1999 2005)))
(print "Triplets < 250: ")
(println (filter (partial every? ludic?) 
         (for [i (range 250)] (list i (+ i 2) (+ i 6)))))
Output:
First 25: (1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107)
Count below 1000: 142
2000th through 2005th: (21475 21481 21487 21493 21503 21511)
Triplets < 250: ((1 3 7) (5 7 11) (11 13 17) (23 25 29) (41 43 47) (173 175 179) (221 223 227) (233 235 239))

Common Lisp

(defun ludic-numbers (max &optional n)
  (loop with numbers = (make-array (1+ max) :element-type 'boolean :initial-element t)
        for i from 2 to max
        until (and n (= num-results (1- n))) ; 1 will be added at the end
        when (aref numbers i)
          collect i into results
          and count t into num-results
          and do (loop for j from i to max
                       count (aref numbers j) into counter
                       when (= (mod counter i) 1)
                         do (setf (aref numbers j) nil))
        finally (return (cons 1 results))))

(defun main ()
  (format t "First 25 ludic numbers:~%")
  (format t "~{~D~^ ~}~%" (ludic-numbers 100 25))
  (terpri)
  (format t "How many ludic numbers <= 1000?~%")
  (format t "~D~%" (length (ludic-numbers 1000)))
  (terpri)
  (let ((numbers (ludic-numbers 30000 2005)))
    (format t "~{#~D: ~D~%~}"
            (mapcan #'list '(2000 2001 2002 2003 2004 2005) (nthcdr 1999 numbers))))
  (terpri)
  (loop with numbers = (ludic-numbers 250)
          initially (format t "Triplets:~%")
        for x in numbers
        when (and (find (+ x 2) numbers)
                  (find (+ x 6) numbers))
          do (format t "~3D ~3D ~3D~%" x (+ x 2) (+ x 6))))
Output:
First 25 ludic numbers:
1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97

How many ludic numbers <= 1000?
142

#2000: 21475
#2001: 21481
#2002: 21487
#2003: 21493
#2004: 21503
#2005: 21511

Triplets:
  1   3   7
  5   7  11
 11  13  17
 23  25  29
 41  43  47
173 175 179
221 223 227
233 235 239

D

opApply Version

Translation of: Python
Translation of: Raku
struct Ludics(T) {
    int opApply(int delegate(in ref T) dg) {
        int result;
        T[] rotor, taken = [T(1)];
        result = dg(taken[0]);
        if (result) return result;

        for (T i = 2; ; i++) { // Shoud be stopped if T has a max.
            size_t j = 0;
            for (; j < rotor.length; j++)
                if (!--rotor[j])
                    break;

            if (j < rotor.length) {
                rotor[j] = taken[j + 1];
            } else {
                result = dg(i);
                if (result) return result;
                taken ~= i;
                rotor ~= taken[j + 1];
            }
        }
    }
}

void main() {
    import std.stdio, std.range, std.algorithm;

    // std.algorithm.take can't be used here.
    uint[] L;
    foreach (const x; Ludics!uint())
        if (L.length < 2005)
            L ~= x;
        else
            break;

    writeln("First 25 ludic primes:\n", L.take(25));
    writefln("\nThere are %d ludic numbers <= 1000.",
             L.until!q{ a > 1000 }.walkLength);

    writeln("\n2000'th .. 2005'th ludic primes:\n", L[1999 .. 2005]);

    enum m = 250;
    const triplets = L.filter!(x => x + 6 < m &&
                                    L.canFind(x + 2) && L.canFind(x + 6))
                     // Ugly output:
                     //.map!(x => tuple(x, x + 2, x + 6)).array;
                     .map!(x => [x, x + 2, x + 6]).array;
    writefln("\nThere are %d triplets less than %d:\n%s",
             triplets.length, m, triplets);
}
Output:
First 25 ludic primes:
[1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107]

There are 142 ludic numbers <= 1000.

2000'th .. 2005'th ludic primes:
[21475, 21481, 21487, 21493, 21503, 21511]

There are 8 triplets less than 250:
[[1, 3, 7], [5, 7, 11], [11, 13, 17], [23, 25, 29], [41, 43, 47], [173, 175, 179], [221, 223, 227], [233, 235, 239]]

The run-time is about 0.03 seconds or less. It takes about 2.0 seconds to generate 50_000 Ludic numbers with ldc2 compiler.

Range Version

This is the same code modified to be a Range.

struct Ludics(T) {
    T[] rotor, taken = [T(1)];
    T i;
    size_t j;
    T front = 1; // = taken[0];
    bool running = false;
    static immutable bool empty = false;

    void popFront() pure nothrow @safe {
        if (running)
            goto RESUME;
        else
            running = true;

        i = 2;
        while (true) {
            j = 0;

            while (j < rotor.length) {
                rotor[j]--;
                if (!rotor[j])
                    break;
                j++;
            }
            if (j < rotor.length) {
                rotor[j] = taken[j + 1];
            } else {
                front = i;
                return;
        RESUME:
                taken ~= i;
                rotor ~= taken[j + 1];
            }
            i++; // Could overflow if T has a max.
        }
    }
}

void main() {
    import std.stdio, std.range, std.algorithm, std.array;

    Ludics!uint L;
    writeln("First 25 ludic primes:\n", L.take(25));
    writefln("\nThere are %d ludic numbers <= 1000.",
             L.until!q{ a > 1000 }.walkLength);

    writeln("\n2000'th .. 2005'th ludic primes:\n", L.drop(1999).take(6));

    enum uint m = 250;
    const few = L.until!(x => x > m).array;
    const triplets = few.filter!(x => x + 6 < m && few.canFind(x + 2)
                                      && few.canFind(x + 6))
                     // Ugly output:
                     //.map!(x => tuple(x, x + 2, x + 6)).array;
                     .map!(x => [x, x + 2, x + 6]).array;
    writefln("\nThere are %d triplets less than %d:\n%s",
             triplets.length, m, triplets);
}

The output is the same. This version is slower, it takes about 3.3 seconds to generate 50_000 Ludic numbers with ldc2 compiler.

Range Generator Version

void main() {
    import std.stdio, std.range, std.algorithm, std.concurrency;

    Generator!T ludics(T)() {
        return new typeof(return)({
            T[] rotor, taken = [T(1)];
            yield(taken[0]);

            for (T i = 2; ; i++) { // Shoud be stopped if T has a max.
                size_t j = 0;
                for (; j < rotor.length; j++)
                    if (!--rotor[j])
                        break;

                if (j < rotor.length) {
                    rotor[j] = taken[j + 1];
                } else {
                    yield(i);
                    taken ~= i;
                    rotor ~= taken[j + 1];
                }
            }
        });
    }

    const L = ludics!uint.take(2005).array;

    writeln("First 25 ludic primes:\n", L.take(25));
    writefln("\nThere are %d ludic numbers <= 1000.",
             L.until!q{ a > 1000 }.walkLength);

    writeln("\n2000'th .. 2005'th ludic primes:\n", L[1999 .. 2005]);

    enum m = 250;
    const triplets = L.filter!(x => x + 6 < m &&
                                    L.canFind(x + 2) && L.canFind(x + 6))
                     // Ugly output:
                     //.map!(x => tuple(x, x + 2, x + 6)).array;
                     .map!(x => [x, x + 2, x + 6]).array;
    writefln("\nThere are %d triplets less than %d:\n%s",
             triplets.length, m, triplets);
}

The result is the same.

Delphi

See Pascal.

Eiffel

class
	LUDIC_NUMBERS

create
	make

feature

	make (n: INTEGER)
			-- Initialized arrays for find_ludic_numbers.
		require
			n_positive: n > 0
		local
			i: INTEGER
		do
			create initial.make_filled (0, 1, n - 1)
			create ludic_numbers.make_filled (1, 1, 1)
			from
				i := 2
			until
				i > n
			loop
				initial.put (i, i - 1)
				i := i + 1
			end
			find_ludic_numbers
		end

	ludic_numbers: ARRAY [INTEGER]

feature {NONE}

	initial: ARRAY [INTEGER]

	find_ludic_numbers
			-- Ludic numbers in array ludic_numbers.
		local
			count: INTEGER
			new_array: ARRAY [INTEGER]
			last: INTEGER
		do
			create new_array.make_from_array (initial)
			last := initial.count
			from
				count := 1
			until
				count > last
			loop
				if ludic_numbers [ludic_numbers.count] /= new_array [1] then
					ludic_numbers.force (new_array [1], count + 1)
				end
				new_array := delete_i_elements (new_array)
				count := count + 1
			end
		end

	delete_i_elements (ar: ARRAY [INTEGER]): ARRAY [INTEGER]
			--- Array with all multiples of 'ar[1]' deleted.
		require
			ar_not_empty: ar.count > 0
		local
			s_array: ARRAY [INTEGER]
			i, k: INTEGER
			length: INTEGER
		do
			create s_array.make_empty
			length := ar.count
			from
				i := 0
				k := 1
			until
				i = length
			loop
				if (i) \\ (ar [1]) /= 0 then
					s_array.force (ar [i + 1], k)
					k := k + 1
				end
				i := i + 1
			end
			if s_array.count = 0 then
				Result := ar
			else
				Result := s_array
			end
		ensure
			not_empty: not Result.is_empty
		end

end

Test:

class
	APPLICATION

create
	make

feature

	make
		local
			k, count: INTEGER
		do
			create ludic.make (22000)
			io.put_string ("%NLudic numbers up to 25. %N")
			across
				ludic.ludic_numbers.subarray (1, 25) as ld
			loop
				io.put_string (ld.item.out + "%N")
			end
			io.put_string ("%NLudic numbers from 2000 ... 2005. %N")
			across
				ludic.ludic_numbers.subarray (2000, 2005) as ld
			loop
				io.put_string (ld.item.out + "%N")
			end
			io.put_string ("%NNumber of Ludic numbers smaller than 1000. %N")
			from
				k := 1
			until
				ludic.ludic_numbers [k] >= 1000
			loop
				k := k + 1
				count := count + 1
			end
			io.put_integer (count)
		end

	ludic: LUDIC_NUMBERS

end
Output:
Ludic numbers up to 25.
1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107

Ludic numbers from 2000 ... 2005.
21475
21481
21487
21493
21503
21511

Number of Ludic numbers smaller than 1000.
142

Elixir

Works with: Elixir version 1.3.1
defmodule Ludic do
  def numbers(n \\ 100000) do
    [h|t] = Enum.to_list(1..n)
    numbers(t, [h])
  end
  
  defp numbers(list, nums) when length(list) < hd(list), do: Enum.reverse(nums, list)
  defp numbers([h|_]=list, nums) do
    Enum.drop_every(list, h) |> numbers([h | nums])
  end
  
  def task do
    IO.puts "First 25 : #{inspect numbers(200) |> Enum.take(25)}"
    IO.puts "Below 1000: #{length(numbers(1000))}"
    tuple = numbers(25000) |> List.to_tuple
    IO.puts "2000..2005th: #{ inspect for i <- 1999..2004, do: elem(tuple, i) }"
    ludic = numbers(250)
    triple = for x <- ludic, x+2 in ludic, x+6 in ludic, do: [x, x+2, x+6]
    IO.puts "Triples below 250: #{inspect triple, char_lists: :as_lists}"
  end
end

Ludic.task
Output:
First 25 : [1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107]
Below 1000: 142
2000..2005th: [21475, 21481, 21487, 21493, 21503, 21511]
Triples below 250: [[1, 3, 7], [5, 7, 11], [11, 13, 17], [23, 25, 29], [41, 43, 47], [173, 175, 179], [221, 223, 227], [233, 235, 239]]

Factor

USING: formatting fry kernel make math math.ranges namespaces
prettyprint.config sequences sequences.extras ;
IN: rosetta-code.ludic-numbers

: next-ludic ( seq -- seq' )
    dup first '[ nip _ mod zero? not ] filter-index ;

: ludics-upto-2005 ( -- a )
    22,000 2 swap [a,b] [ ! 22k suffices to produce 2005 ludics
        1 , [ building get length 2005 = ]
        [ dup first , next-ludic ] until drop
    ] { } make ;

: ludic-demo ( -- )
    100 margin set ludics-upto-2005
    [ 6 tail* ] [ [ 1000 < ] count ] [ 25 head ] tri
    "First 25 ludic numbers:\n%u\n\n"
    "Count of ludic numbers less than 1000:\n%d\n\n"
    "Ludic numbers 2000 to 2005:\n%u\n" [ printf ] tri@ ;

MAIN: ludic-demo
Output:
First 25 ludic numbers:
{ 1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107 }

Count of ludic numbers less than 1000:
142

Ludic numbers 2000 to 2005:
{ 21475 21481 21487 21493 21503 21511 }

Fortran

Works with: Fortran version 95 and later
program ludic_numbers
  implicit none
  
  integer, parameter :: nmax = 25000
  logical :: ludic(nmax) = .true.
  integer :: i, j, n

  do i = 2, nmax / 2
    if (ludic(i)) then
      n = 0
      do j = i+1, nmax
        if(ludic(j)) n = n + 1
        if(n == i) then
          ludic(j) = .false.
          n = 0
        end if
      end do
    end if
  end do

  write(*, "(a)", advance = "no") "First 25 Ludic numbers: "
  n = 0
  do i = 1, nmax
    if(ludic(i)) then
      write(*, "(i0, 1x)", advance = "no") i
      n = n + 1
    end if
    if(n == 25) exit
  end do  
   
  write(*, "(/, a)", advance = "no") "Ludic numbers below 1000: "
  write(*, "(i0)") count(ludic(:999))
 
  write(*, "(a)", advance = "no") "Ludic numbers 2000 to 2005: " 
  n = 0
  do i = 1, nmax
    if(ludic(i)) then
       n = n + 1
       if(n >= 2000) then
         write(*, "(i0, 1x)", advance = "no") i
         if(n == 2005) exit
       end if
     end if
  end do  

  write(*, "(/, a)", advance = "no") "Ludic Triplets below 250: "
  do i = 1, 243
    if(ludic(i) .and. ludic(i+2) .and. ludic(i+6)) then
       write(*, "(a, 2(i0, 1x), i0, a, 1x)", advance = "no") "[", i, i+2, i+6, "]"
    end if  
  end do

end program

Output:

First 25 Ludic numbers: 1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107 
Ludic numbers below 1000: 142
Ludic numbers 2000 to 2005: 21475 21481 21487 21493 21503 21511 
Ludic Triplets below 250: [1 3 7] [5 7 11] [11 13 17] [23 25 29] [41 43 47] [173 175 179] [221 223 227] [233 235 239]

FreeBASIC

' FB 1.05.0 Win64

' As it would be too expensive to actually remove elements from the array
' we instead set an element to 0 if it has been removed.

Sub ludic(n As Integer, lu() As Integer)
  If n < 1 Then Return
  Redim lu(1 To n)
  lu(1) = 1
  If n = 1 Then Return
  Dim As Integer count = 1, count2
  Dim As Integer i, j, k = 1
  Dim As Integer ub = 22000 '' big enough to deal with up to 2005 ludic numbers
  Dim a(2 To ub) As Integer
  For i = 2 To ub : a(i) = i : Next

  Do
     k += 1

     For i = k to ub
       If a(i) > 0 Then 
         count += 1 
         lu(count) = a(i)
         If n = count Then Return
         a(i) = 0  
         k = i             
         Exit For
       End If
     Next 

     count2 = 0
     j = k + 1 

     While j <= ub
       If a(j) > 0 Then
         count2 +=1
         If count2 = k Then
           a(j) = 0
           count2 = 0
         End If
       End If
       j += 1
     Wend
   Loop
     
End Sub

Dim i As Integer
Dim lu() As Integer
ludic(2005, lu())
Print "The first 25 Ludic numbers are :" 
For i = 1 To 25
  Print Using "###"; lu(i); 
  Print " ";
Next
Print

Dim As Integer Count  = 0
For i = 1 To 1000 
  If lu(i) <= 1000 Then
    count += 1
  Else
    Exit For
  End If
Next
Print
Print "There are"; count; " Ludic numbers <= 1000"
Print

Print "The 2000th to 2005th Ludics are :"
For i = 2000 To 2005
  Print lu(i); " ";
Next
Print : Print

Print "The Ludic triplets below 250 are : "
Dim As Integer j, k, ldc
Dim b As Boolean
For i = 1 To 248
   ldc = lu(i)
   If ldc >= 244 Then Exit For
   b = False
   For j = i + 1 To 249
     If lu(j) = ldc + 2 Then
       b = True
       k = j
       Exit For
     ElseIf lu(j) > ldc + 2 Then
       Exit For
     End If
   Next j
   If b = False Then Continue For
   For j = k + 1 To 250
     If lu(j) = ldc + 6 Then
       Print "("; Str(ldc); ","; ldc + 2; ","; ldc + 6; ")"
       Exit For
     ElseIf lu(j) > ldc + 6 Then
       Exit For
     End If
   Next j
Next i
Erase lu
Print 

Print "Press any key to quit"
Sleep
Output:
The first 25 Ludic numbers are :
  1   2   3   5   7  11  13  17  23  25  29  37  41  43  47  53  61  67  71  77
 83  89  91  97 107

There are 142 Ludic numbers <= 1000

The 2000th to 2005th Ludics are :
 21475  21481  21487  21493  21503  21511

The Ludic triplets below 250 are :
(1, 3, 7)
(5, 7, 11)
(11, 13, 17)
(23, 25, 29)
(41, 43, 47)
(173, 175, 179)
(221, 223, 227)
(233, 235, 239)

Go

package main

import "fmt"

// Ludic returns a slice of Ludic numbers stopping after
// either n entries or when max is exceeded.
// Either argument may be <=0 to disable that limit.
func Ludic(n int, max int) []uint32 {
	const maxInt32 = 1<<31 - 1 // i.e. math.MaxInt32
	if max > 0 && n < 0 {
		n = maxInt32
	}
	if n < 1 {
		return nil
	}
	if max < 0 {
		max = maxInt32
	}
	sieve := make([]uint32, 10760) // XXX big enough for 2005 Ludics
	sieve[0] = 1
	sieve[1] = 2
	if n > 2 {
		// We start with even numbers already removed
		for i, j := 2, uint32(3); i < len(sieve); i, j = i+1, j+2 {
			sieve[i] = j
		}
		// We leave the Ludic numbers in place,
		// k is the index of the next Ludic
		for k := 2; k < n; k++ {
			l := int(sieve[k])
			if l >= max {
				n = k
				break
			}
			i := l
			l--
			// last is the last valid index
			last := k + i - 1
			for j := k + i + 1; j < len(sieve); i, j = i+1, j+1 {
				last = k + i
				sieve[last] = sieve[j]
				if i%l == 0 {
					j++
				}
			}
			// Truncate down to only the valid entries
			if last < len(sieve)-1 {
				sieve = sieve[:last+1]
			}
		}
	}
	if n > len(sieve) {
		panic("program error") // should never happen
	}
	return sieve[:n]
}

func has(x []uint32, v uint32) bool {
	for i := 0; i < len(x) && x[i] <= v; i++ {
		if x[i] == v {
			return true
		}
	}
	return false
}

func main() {
	// Ludic() is so quick we just call it repeatedly
	fmt.Println("First 25:", Ludic(25, -1))
	fmt.Println("Numner of Ludics below 1000:", len(Ludic(-1, 1000)))
	fmt.Println("Ludic 2000 to 2005:", Ludic(2005, -1)[1999:])

	fmt.Print("Tripples below 250:")
	x := Ludic(-1, 250)
	for i, v := range x[:len(x)-2] {
		if has(x[i+1:], v+2) && has(x[i+2:], v+6) {
			fmt.Printf(", (%d %d %d)", v, v+2, v+6)
		}
	}
	fmt.Println()
}

Run in Go Playground.

Output:
First 25: [1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107]
Numner of Ludics below 1000: 142
Ludic 2000 to 2005: [21475 21481 21487 21493 21503 21511]
Tripples below 250:, (1 3 7), (5 7 11), (11 13 17), (23 25 29), (41 43 47), (173 175 179), (221 223 227), (233 235 239)

Haskell

import Data.List (unfoldr, genericSplitAt)

ludic :: [Integer]
ludic = 1 : unfoldr (\xs@(x:_) -> Just (x, dropEvery x xs)) [2 ..]
  where
    dropEvery n = concatMap tail . unfoldr (Just . genericSplitAt n)

main :: IO ()
main = do
  print $ take 25 ludic
  (print . length) $ takeWhile (<= 1000) ludic
  print $ take 6 $ drop 1999 ludic
-- haven't done triplets task yet
Output:
[1,2,3,5,7,11,13,17,23,25,29,37,41,43,47,53,61,67,71,77,83,89,91,97,107]
142
[21475,21481,21487,21493,21503,21511]

The filter for dropping every n-th number can be delayed until it's needed, which speeds up the generator, more so when a longer sequence is taken.

ludic = 1:2 : f 3 [3..] [(4,2)] where
	f n (x:xs) yy@((i,y):ys)
		| n == i = f n (dropEvery y xs) ys
		| otherwise = x : f (1+n) xs (yy ++ [(n+x, x)])

dropEvery n s = a ++ dropEvery n (tail b) where
	(a,b) = splitAt (n-1) s

main = print $ ludic !! 10000

Icon and Unicon

This is inefficient, but was fun to code as a cascade of filters. Works in both languages.

global num, cascade, sieve, nfilter

procedure main(A)
    lds := ludic(2005)		# All we need for the four tasks.
    every writes("First 25:" | (" "||!lds)\25 | "\n")
    every (n := 0) +:= (!lds < 1000, 1)
    write("There are ",n," Ludic numbers < 1000.")
    every writes("2000th through 2005th: " | (lds[2000 to 20005]||" ") | "\n")
    writes("Triplets:")
    every (250 > (x := !lds)) & (250 > (x+2 = !lds)) & (250 > (x+6 = !lds)) do
        writes(" [",x,",",x+2,",",x+6,"]")
    write()
end

procedure ludic(limit)
    candidates := create seq(2)
    put(cascade := [], create {
        repeat {
            report(l := num, limit)
            put(cascade, create (cnt:=0, repeat ((cnt+:=1)%l=0, @sieve) | @@nfilter))
            cascade[-2] :=: cascade[-1]  # keep this sink as the last filter
            @sieve
            }
        })
    sieve := create while num := @candidates do @@(nfilter := create !cascade)
    report(1, limit)
    return @sieve
end

procedure report(ludic, limit)
    static count, lds
    initial {count := 0; lds := []}
    if (count +:= 1) > limit then lds@&main
    put(lds, ludic)
end

Output:

->ludic    
First 25: 1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107
There are 142 Ludic numbers < 1000.
2000th through 20005th: 21475 21481 21487 21493 21503 21511 
Triplets: [1,3,7] [5,7,11] [11,13,17] [23,25,29] [41,43,47] [173,175,179] [221,223,227] [233,235,239]
->

J

Solution (naive / brute force):
   ludic =: _1 |.!.1 [: {."1 [: (#~ 0 ~: {. | i.@#)^:a: 2 + i.
Examples:
   # ludic 110  NB. 110 is sufficient to generate 25 Ludic numbers
25
   ludic 110    NB. First 25 Ludic numbers
1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107

   #ludic 1000  NB. 142 Ludic numbers <= 1000
142

   # ludic 22000   NB. 22000 is sufficient to generate > 2005 Ludic numbers
2042
   (2000+i.6) { ludic 22000  NB. Ludic numbers 2000-2005
21481 21487 21493 21503 21511 21523

   0 2 6 (] (*./ .e.~ # |:@]) +/) ludic 250  NB. Ludic triplets <= 250
  1   3   7
  5   7  11
 11  13  17
 23  25  29
 41  43  47
173 175 179
221 223 227
233 235 239

Java

Works with: Java version 1.5+

This example uses pre-calculated ranges for the first and third task items (noted in comments).

import java.util.ArrayList;
import java.util.List;

public class Ludic{
	public static List<Integer> ludicUpTo(int n){
		List<Integer> ludics = new ArrayList<Integer>(n);
		for(int i = 1; i <= n; i++){   //fill the initial list
			ludics.add(i);
		}
		
		//start at index 1 because the first ludic number is 1 and we don't remove anything for it
		for(int cursor = 1; cursor < ludics.size(); cursor++){
			int thisLudic = ludics.get(cursor); //the first item in the list is a ludic number
			int removeCursor = cursor + thisLudic; //start removing that many items later
			while(removeCursor < ludics.size()){
				ludics.remove(removeCursor);		     //remove the next item
				removeCursor = removeCursor + thisLudic - 1; //move the removal cursor up as many spaces as we need to
									     //then back one to make up for the item we just removed
			}
		}
		return ludics;
	}
	
	public static List<List<Integer>> getTriplets(List<Integer> ludics){
		List<List<Integer>> triplets = new ArrayList<List<Integer>>();
		for(int i = 0; i < ludics.size() - 2; i++){ //only need to check up to the third to last item
			int thisLudic = ludics.get(i);
			if(ludics.contains(thisLudic + 2) && ludics.contains(thisLudic + 6)){
				List<Integer> triplet = new ArrayList<Integer>(3);
				triplet.add(thisLudic);
				triplet.add(thisLudic + 2);
				triplet.add(thisLudic + 6);
				triplets.add(triplet);
			}
		}
		return triplets;
	}
	
	public static void main(String[] srgs){
		System.out.println("First 25 Ludics: " + ludicUpTo(110));				//110 will get us 25 numbers
		System.out.println("Ludics up to 1000: " + ludicUpTo(1000).size());
		System.out.println("2000th - 2005th Ludics: " + ludicUpTo(22000).subList(1999, 2005));  //22000 will get us 2005 numbers
		System.out.println("Triplets up to 250: " + getTriplets(ludicUpTo(250)));
	}
}
Output:
First 25 Ludics: [1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107]
Ludics up to 1000: 142
2000th - 2005th Ludics: [21475, 21481, 21487, 21493, 21503, 21511]
Triplets up to 250: [[1, 3, 7], [5, 7, 11], [11, 13, 17], [23, 25, 29], [41, 43, 47], [173, 175, 179], [221, 223, 227], [233, 235, 239]]

JavaScript

ES6

/**
 * Boilerplate to simply get an array filled between 2 numbers
 * @param {!number} s Start here (inclusive)
 * @param {!number} e End here (inclusive)
 */
const makeArr = (s, e) => new Array(e + 1 - s).fill(s).map((e, i) => e + i);

/**
 * Remove every n-th element from the given array
 * @param {!Array} arr
 * @param {!number} n
 * @return {!Array}
 */
const filterAtInc = (arr, n) => arr.filter((e, i) => (i + 1) % n);

/**
 * Generate ludic numbers
 * @param {!Array} arr
 * @param {!Array} result
 * @return {!Array}
 */
const makeLudic = (arr, result) => {
  const iter = arr.shift();
  result.push(iter);
  return arr.length ? makeLudic(filterAtInc(arr, iter), result) : result;
};

/**
 * Our Ludic numbers. This is a bit of a cheat, as we already know beforehand
 * up to where our seed array needs to go in order to exactly get to the
 * 2005th Ludic number.
 * @type {!Array<!number>}
 */
const ludicResult = makeLudic(makeArr(2, 21512), [1]);


// Below is just logging out the results.
/**
 * Given a number, return a function that takes an array, and return the
 * count of all elements smaller than the given
 * @param {!number} n
 * @return {!Function}
 */
const smallerThanN = n => arr => {
  return arr.reduce((p,c) => {
    return c <= n ? p + 1 : p
  }, 0)
};
const smallerThan1K = smallerThanN(1000);

console.log('\nFirst 25 Ludic Numbers:');
console.log(ludicResult.filter((e, i) => i < 25).join(', '));

console.log('\nTotal Ludic numbers smaller than 1000:');
console.log(smallerThan1K(ludicResult));

console.log('\nThe 2000th to 2005th ludic numbers:');
console.log(ludicResult.filter((e, i) => i > 1998).join(', '));

console.log('\nTriplets smaller than 250:');
ludicResult.forEach(e => {
  if (e + 6 < 250 && ludicResult.indexOf(e + 2) > 0 && ludicResult.indexOf(e + 6) > 0) {
    console.log([e, e + 2, e + 6].join(', '));
  }
});
First 25 Ludic Numbers:
1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107

Total Ludic numbers smaller than 1000:
142

The 2000th to 2005th ludic numbers:
21475, 21481, 21487, 21493, 21503, 21511

Triplets smaller than 250:
1, 3, 7
5, 7, 11
11, 13, 17
23, 25, 29
41, 43, 47
173, 175, 179
221, 223, 227
233, 235, 239

jq

Works with: jq

In this entry, for each task, we do not assume any prior calculation of how big the initial sieve must be. That is, an adaptive approach is taken.

# This method for sieving turns out to be the fastest in jq.
# Input: an array to be sieved.
# Output: if the array length is less then $n then empty, else the sieved array.
def sieve($n):
  if length<$n then empty
  else . as $in
  | reduce range(0;length) as $i ([]; if $i % $n == 0 then . else . + [$in[$i]]  end)
  end;

# Generate a stream of ludic numbers based on sieving range(2; $nmax+1)
def ludic($nmax):
  def l:
    .[0] as $next
    | $next, (sieve($next)|l);
  1, ([range(2; $nmax+1)] | l);

# Output: an array of the first . ludic primes (including 1)
def first_ludic_primes:
  . as $n
  | def l:
      . as $k
      | [ludic(10*$k)] as $a
      | if ($a|length) >= $n then $a[:$n]
        else (10*$k) | l
        end;
   l;

# Output: an array of the ludic numbers less than .
def ludic_primes:
  . as $n
  | def l:
      . as $k
      | [ludic(10*$k)] as $a
      | if $a[-1] >= $n then $a | map(select(. < $n))
        else (10*$k) | l
        end;
   l;
  
# Output; a stream of triplets of ludic numbers, where each member of the triplet is less than .
def triplets:
  ludic_primes as $primes
  | $primes[] as $p
  | $primes
  | bsearch($p) as $i
  | if $i >= 0
    then $primes[$i+1:]
    | select( bsearch($p+2) >= 0 and
              bsearch($p+6) >= 0)
    | [$p, $p+2, $p+6]
    else empty
    end;


"First 25 ludic primes:", (25|first_ludic_primes),
"\nThere are \(1000|ludic_primes|length) ludic numbers <= 1000",
( "The \n2000th to 2005th ludic primes are:",
 (2005|first_ludic_primes)[2000:]),
( [250 | triplets] 
  | "\nThere are \(length) triplets less than 250:",
    .[] )
Output:
First 25 ludic primes:
[1,2,3,5,7,11,13,17,23,25,29,37,41,43,47,53,61,67,71,77,83,89,91,97,107]

There are 142 ludic numbers <= 1000

2000th to 2005th ludic primes:
[21481,21487,21493,21503,21511]

There are 8 triplets less than 250:
[1,3,7]
[5,7,11]
[11,13,17]
[23,25,29]
[41,43,47]
[173,175,179]
[221,223,227]
[233,235,239]


Julia

function ludic_filter{T<:Integer}(n::T)
    0 < n || throw(DomainError())
    slud = trues(n)
    for i in 2:(n-1)
        slud[i] || continue
        x = 0
        for j in (i+1):n
            slud[j] || continue
            x += 1
            x %= i
            x == 0 || continue
            slud[j] = false
        end
    end
    return slud
end

ludlen = 10^5
slud = ludic_filter(ludlen)
ludics = collect(1:ludlen)[slud]

n = 25
println("Generate and show here the first ", n, " ludic numbers.")
print("    ")
crwid = 76
wid = 0
for i in 1:(n-1)
    s = @sprintf "%d, " ludics[i]
    wid += length(s)
    if crwid < wid
        print("\n    ")
        wid = 0
    end
    print(s)
end
println(ludics[n])

n = 10^3
println()
println("How many ludic numbers are there less than or equal to ", n, "?")
println("    ", sum(slud[1:n]))

lo = 2000
hi = lo+5
println()
println("Show the ", lo, "..", hi, "'th ludic numbers.")
for i in lo:hi
    println("    Ludic(", i, ") = ", ludics[i])
end

n = 250
println()
println("Show all triplets of ludic numbers < ", n)
for i = 1:n-7
    slud[i] || continue
    j = i+2
    slud[j] || continue
    k = i+6
    slud[k] || continue
    println("    ", i, ", ", j, ", ", k)
end
Output:
Generate and show here the first 25 ludic numbers.
    1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 
    83, 89, 91, 97, 107

How many ludic numbers are there less than or equal to 1000?
    142

Show the 2000..2005'th ludic numbers.
    Ludic(2000) = 21475
    Ludic(2001) = 21481
    Ludic(2002) = 21487
    Ludic(2003) = 21493
    Ludic(2004) = 21503
    Ludic(2005) = 21511

Show all triplets of ludic numbers < 250
    1, 3, 7
    5, 7, 11
    11, 13, 17
    23, 25, 29
    41, 43, 47
    173, 175, 179
    221, 223, 227
    233, 235, 239

Kotlin

Translation of: FreeBASIC
// version 1.0.6

/* Rather than remove elements from a MutableList which would be a relatively expensive operation
   we instead use two arrays:
   
   1. An array of the Ludic numbers to be returned.
   2. A 'working' array of a suitable size whose elements are set to 0 to denote removal. */

fun ludic(n: Int): IntArray {
    if (n < 1) return IntArray(0)
    val lu = IntArray(n)  // array of Ludic numbers required
    lu[0] = 1
    if (n == 1) return lu
    var count = 1
    var count2: Int
    var j: Int
    var k = 1
    var ub = n * 11  // big enough to deal with up to 2005 ludic numbers
    val a = IntArray(ub) { it }  // working array
    while (true) {
        k += 1
        for (i in k until ub) {
            if (a[i] > 0) {
                count +=1
                lu[count - 1] = a[i]
                if (n == count) return lu
                a[i] = 0
                k = i
                break
            }
        }
        count2 = 0
        j = k + 1
        while (j < ub) {
            if (a[j] > 0) {
                count2 +=1
                if (count2 == k) {
                    a[j] = 0
                    count2 = 0
                }
            }
            j += 1
        }
    }
} 

fun main(args: Array<String>) {
    val lu: IntArray = ludic(2005)
    println("The first 25 Ludic numbers are :")  
    for (i in 0 .. 24) print("%4d".format(lu[i]))
  
    val count = lu.count { it <= 1000 }
    println("\n\nThere are $count Ludic numbers <= 1000" )

    println("\nThe 2000th to 2005th Ludics are :")
    for (i in 1999 .. 2004) print("${lu[i]}  ")

    println("\n\nThe Ludic triplets below 250 are : ")
    var k: Int = 0
    var ldc: Int
    var b: Boolean
    for (i in 0 .. 247) {
        ldc = lu[i]
        if (ldc >= 244) break
        b = false
        for (j in i + 1 .. 248) {
             if (lu[j] == ldc + 2) {
                 b = true
                 k = j
                 break
             }
             else if (lu[j] > ldc + 2) break
        }
        if (!b) continue
        for (j in k + 1 .. 249) {
            if (lu[j] == ldc + 6) {
                println("($ldc, ${ldc + 2}, ${ldc + 6})")
                break
            }
            else if (lu[j] > ldc + 6) break
        }
    }    
}
Output:
The first 25 Ludic numbers are :
   1   2   3   5   7  11  13  17  23  25  29  37  41  43  47  53  61  67  71  77  83  89  91  97 107

There are 142 Ludic numbers <= 1000

The 2000th to 2005th Ludics are :
21475  21481  21487  21493  21503  21511

The Ludic triplets below 250 are :
(1, 3, 7)
(5, 7, 11)
(11, 13, 17)
(23, 25, 29)
(41, 43, 47)
(173, 175, 179)
(221, 223, 227)
(233, 235, 239)

Lua

-- Return table of ludic numbers below limit
function ludics (limit)
    local ludList, numList, index = {1}, {}
    for n = 2, limit do table.insert(numList, n) end
    while #numList > 0 do
        index = numList[1]
        table.insert(ludList, index)
        for key = #numList, 1, -1 do
            if key % index == 1 then table.remove(numList, key) end
        end
    end
    return ludList
end

-- Return true if n is found in t or false otherwise
function foundIn (t, n)
    for k, v in pairs(t) do
        if v == n then return true end
    end
    return false
end

-- Display msg followed by all values in t
function show (msg, t)
    io.write(msg)
    for _, v in pairs(t) do io.write(" " .. v) end
    print("\n")
end

-- Main procedure
local first25, under1k, inRange, tripList, triplets = {}, 0, {}, {}, {}
for k, v in pairs(ludics(30000)) do
    if k <= 25 then table.insert(first25, v) end
    if v <= 1000 then under1k = under1k + 1 end
    if k >= 2000 and k <= 2005 then table.insert(inRange, v) end
    if v < 250 then table.insert(tripList, v) end
end
for _, x in pairs(tripList) do
    if foundIn(tripList, x + 2) and foundIn(tripList, x + 6) then
        table.insert(triplets, "\n{" .. x .. "," .. x+2 .. "," .. x+6 .. "}")
    end
end
show("First 25:", first25)
print(under1k .. " are less than or equal to 1000\n")
show("2000th to 2005th:", inRange)
show("Triplets:", triplets)
Output:
First 25: 1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107

142 are less than or equal to 1000

2000th to 2005th: 21475 21481 21487 21493 21503 21511

Triplets:
{1,3,7}
{5,7,11}
{11,13,17}
{23,25,29}
{41,43,47}
{173,175,179}
{221,223,227}
{233,235,239}

Mathematica/Wolfram Language

n=10^5;
Ludic={1};
seq=Range[2,n];
ClearAll[DoStep]
DoStep[seq:{f_,___}]:=Module[{out=seq},
 AppendTo[Ludic,f];
 out[[;;;;f]]=Sequence[];
 out
]
Nest[DoStep,seq,2500];

Ludic[[;; 25]]
LengthWhile[Ludic, # < 1000 &]
Ludic[[2000 ;; 2005]]
Select[Subsets[Select[Ludic, # < 250 &], {3}], Differences[#] == {2, 4} &]
Output:
{1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107}
142
{21475, 21481, 21487, 21493, 21503, 21511}
{{1, 3, 7}, {5, 7, 11}, {11, 13, 17}, {23, 25, 29}, {41, 43, 47}, {173, 175, 179}, {221, 223, 227}, {233, 235, 239}}

Nim

Ludic number generation is inspired by Python lazy streaming generator. Note that to store the ludic numbers we have chosen to use an array rather than a sequence, which allows to use 1-based indexes.

import strutils

type LudicArray[N: static int] = array[1..N, int]

func initLudicArray[N: static int](): LudicArray[N] =
  ## Initialize an array of ludic numbers.
  result[1] = 1
  for i in 2..N:
    var k = 0
    for j in countdown(i - 1, 2):
      k = k * result[j] div (result[j] - 1) + 1
    result[i] = k + 2


proc print(text: string; list: openArray[int]) =
  ## Print a text followed by a list of ludic numbers.
  var line = text
  let start = line.len
  for val in list:
    line.addSep(", ", start)
    line.add $val
  echo line


func isLudic(ludicArray: LudicArray; n, start: Positive): bool =
  ## Check if a number "n" is ludic, starting search from index "start".
  for idx in start..ludicArray.N:
    let val = ludicArray[idx]
    if n == val: return true
    if n < val: break


when isMainModule:

  let ludicArray = initLudicArray[2005]()

  print "The 25 first ludic numbers are: ", ludicArray[1..25]

  var count = 0
  for n in ludicArray:
    if n > 1000: break
    inc count
  echo "\nThere are ", count, " ludic numbers less or equal to 1000."

  print "\nThe 2000th to 2005th ludic numbers are: ", ludicArray[2000..2005]

  echo "\nThe triplets of ludic numbers less than 250 are:"
  var line = ""
  for i, n in ludicArray:
    if n >= 244:
      echo line
      break
    if ludicArray.isLudic(n + 2, i + 1) and ludicArray.isLudic(n + 6, i + 2):
      line.addSep(", ")
      line.add "($1, $2, $3)".format(n, n + 2, n + 6)
Output:
The 25 first ludic numbers are: 1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107

There are 142 ludic numbers less or equal to 1000.

The 2000th to 2005th ludic numbers are: 21475, 21481, 21487, 21493, 21503, 21511

The triplets of ludic numbers less than 250 are:
(1, 3, 7), (5, 7, 11), (11, 13, 17), (23, 25, 29), (41, 43, 47), (173, 175, 179), (221, 223, 227), (233, 235, 239)

Objeck

Translation of: Java
use Collection.Generic;

class Ludic  {
  function : Main(args : String[]) ~ Nil {
    ludics := LudicUpTo(110);
    Show("First 25 Ludics: ", ludics, 0, ludics->Size());
    System.IO.Console->Print("Ludics up to 1000: ")->PrintLine(LudicUpTo(1000)->Size());
    ludics := LudicUpTo(22000);
    Show("2000th - 2005th Ludics: ", ludics, 1999, 2005);
    Show("Triplets up to 250: ", GetTriplets(LudicUpTo(250)));
  }
  
  function : LudicUpTo(n : Int) ~ CompareVector<IntHolder> {
    ludics := CompareVector->New()<IntHolder>;
    for(i := 1; i <= n; i++;){
      ludics->AddBack(i);
    };
     
    for(cursor := 1; cursor < ludics->Size(); cursor++;) {
      thisLudic := ludics->Get(cursor);
      removeCursor := cursor + thisLudic;
      while(removeCursor < ludics->Size()){
        ludics->Remove(removeCursor);
        removeCursor := removeCursor + thisLudic - 1;
      };
    };

    return ludics;
  }

  function : GetTriplets(ludics : CompareVector<IntHolder>) ~ Vector<CompareVector<IntHolder> > {
    triplets := Vector->New()<CompareVector<IntHolder> >;

    for(i := 0; i < ludics->Size() - 2; i++;){
      thisLudic := ludics->Get(i);
      if(ludics->Has(thisLudic + 2) & ludics->Has(thisLudic + 6)){
        triplet := CompareVector->New()<IntHolder>;
        triplet->AddBack(thisLudic);
        triplet->AddBack(thisLudic + 2);
        triplet->AddBack(thisLudic + 6);
        triplets->AddBack(triplet);
      };
    };

    return triplets;
  }

  function : Show(title : String, ludics : CompareVector<IntHolder>, start : Int, end : Int) ~ Nil {
    title->Print();
    '['->Print();
    for(i := start; i < end; i +=1;) {
      ludics->Get(i)->Get()->Print();
      if(i + 1 < ludics->Size()) {
        ','->Print();
      };
    };
    ']'->PrintLine();
  }

  function : Show(title : String, triplets : Vector<CompareVector<IntHolder> >) ~ Nil {
    title->PrintLine();
    each(i : triplets) {
      triplet := triplets->Get(i);
      Show("\t", triplet, 0, triplet->Size());
    };
  }
}
Output:
First 25 Ludics: [1,2,3,5,7,11,13,17,23,25,29,37,41,43,47,53,61,67,71,77,83,89,91,97,107]
Ludics up to 1000: 142
2000th - 2005th Ludics: [21475,21481,21487,21493,21503,21511,]
Triplets up to 250:
        [1,3,7]
        [5,7,11]
        [11,13,17]
        [23,25,29]
        [41,43,47]
        [173,175,179]
        [221,223,227]
        [233,235,239]

Oforth

: ludic(n)
| ludics l p |
   ListBuffer newSize(n) seqFrom(2, n) over addAll ->l
   ListBuffer newSize(n) dup add(1) dup ->ludics

   while(l notEmpty) [
      l removeFirst dup ludics add ->p  
      l size p / p * while(dup 1 > ) [ dup l removeAt drop p - ] drop
      ] ;

: ludics
| l i |
   ludic(22000) ->l
   "First 25     : " print l left(25) println
   "Below 1000   : " print l filter(#[ 1000 < ]) size println
   "2000 to 2005 : " print l extract(2000, 2005) println

   250 loop: i [
      l include(i) ifFalse: [ continue ]
      l include(i 2 +) ifFalse: [ continue ]
      l include(i 6 +) ifFalse: [ continue ]
      i print ", " print i 2 + print ", " print i 6 + println
      ] ;
Output:
First 25     : [1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107]
Below 1000   : 142
2000 to 2005 : [21475, 21481, 21487, 21493, 21503, 21511]
1, 3, 7
5, 7, 11
11, 13, 17
23, 25, 29
41, 43, 47
173, 175, 179
221, 223, 227
233, 235, 239

PARI/GP

Works with: PARI/GP version 2.7.4 and above

Version #1. Creating vector of ludic numbers' flags, where the index of each flag=1 is the ludic number.

\\ Creating Vlf - Vector of ludic numbers' flags,
\\ where the index of each flag=1 is the ludic number.
\\ 2/28/16 aev
ludic(maxn)={my(Vlf=vector(maxn,z,1),n2=maxn\2,k,j1);
for(i=2,n2, 
    if(Vlf[i], k=0; j1=i+1;
       for(j=j1,maxn, if(Vlf[j], k++); if(k==i, Vlf[j]=0; k=0))
      ); 
   );
return(Vlf);
}

{
\\ Required tests:
my(Vr,L=List(),k=0,maxn=25000);
Vr=ludic(maxn);
print("The first 25 Ludic numbers: ");
for(i=1,maxn, if(Vr[i]==1, k++; print1(i," "); if(k==25, break)));
print("");print("");
k=0;
for(i=1,999, if(Vr[i]==1, k++));
print("Ludic numbers below 1000: ",k);
print("");
k=0;
print("Ludic numbers 2000 to 2005: ");
for(i=1,maxn, if(Vr[i]==1, k++; if(k>=2000&&k<=2005, listput(L,i)); if(k>2005, break)));
for(i=1,6, print1(L[i]," "));
print(""); print("");
print("Ludic Triplets below 250: ");
for(i=1,250, if(Vr[i]&&Vr[i+2]&&Vr[i+6], print1("(",i," ",i+2," ",i+6,") ")));
}
Output:
The first 25 Ludic numbers:
1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107

Ludic numbers below 1000: 142

Ludic numbers 2000 to 2005:
21475 21481 21487 21493 21503 21511

Ludic Triplets below 250:
(1 3 7) (5 7 11) (11 13 17) (23 25 29) (41 43 47) (173 175 179) (221 223 227) (233 235 239)

Version #2. Creating vector of ludic numbers.

Upgraded script from A003309 to meet task requirements.

\\ Creating Vl - Vector of ludic numbers.
\\ 2/28/16 aev
ludic2(maxn)={my(Vw=vector(maxn, x, x+1),Vl=Vec([1]),vwn=#Vw,i);
while(vwn>0, i=Vw[1]; Vl=concat(Vl,[i]);
 Vw=vector((vwn*(i-1))\i,x,Vw[(x*i+i-2)\(i-1)]); vwn=#Vw
); return(Vl);
}
{
\\ Required tests:
my(Vr,L=List(),k=0,maxn=22000,vrs,vi);
Vr=ludic2(maxn); vrs=#Vr;
print("The first 25 Ludic numbers: ");
for(i=1,25, print1(Vr[i]," "));
print("");print("");
k=0;
for(i=1,vrs, if(Vr[i]<1000, k++, break));
print("Ludic numbers below 1000: ",k);
print("");
k=0;
print("Ludic numbers 2000 to 2005: ");
for(i=2000,2005, print1(Vr[i]," "));
print("");print("");
print("Ludic Triplets below 250: ");
for(i=1,vrs, vi=Vr[i]; if(i==1,print1("(",vi," ",vi+2," ",vi+6,") "); next); if(vi+6<250,if(Vr[i+1]==vi+2&&Vr[i+2]==vi+6, print1("(",vi," ",vi+2," ",vi+6,") "))));
}
Output:
The first 25 Ludic numbers:
1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107

Ludic numbers below 1000: 142

Ludic numbers 2000 to 2005:
21475 21481 21487 21493 21503 21511

Ludic Triplets below 250:
(1 3 7) (5 7 11) (11 13 17) (23 25 29) (41 43 47) (173 175 179) (221 223 227) (233 235 239)

Pascal

Inspired by "rotors" of Raku. Runtime nearly quadratic: maxLudicCnt = 10000 -> 0.03 s =>maxLudicCnt= 100000 -> 3 s

program lucid;
{$IFDEF FPC}
  {$MODE objFPC} // useful for x64
{$ENDIF}

const
  //66164 -> last < 1000*1000;
  maxLudicCnt = 2005;//must be > 1
type

  tDelta = record
             dNum,
             dCnt : LongInt;
           end;

  tpDelta = ^tDelta;
  tLudicList = array of tDelta;

  tArrdelta =array[0..0] of tDelta;
  tpLl = ^tArrdelta;

function isLudic(plL:tpLl;maxIdx:nativeInt):boolean;
var
  i,
  cn : NativeInt;
Begin
  //check if n is 'hit' by a prior ludic number
  For i := 1 to maxIdx do
    with plL^[i] do
    Begin
      //Mask read modify write reread
      //dec(dCnt);IF dCnt= 0
      cn := dCnt;
      IF cn = 1 then
      Begin
        dcnt := dNum;
        isLudic := false;
        EXIT;
       end;
      dcnt := cn-1;
    end;
  isLudic := true;
end;

procedure CreateLudicList(var Ll:tLudicList);
var
  plL : tpLl;
  n,LudicCnt : NativeUint;
begin
  // special case 1
  n := 1;
  Ll[0].dNum := 1;

  plL := @Ll[0];
  LudicCnt := 0;
  repeat
    inc(n);
    If isLudic(plL,LudicCnt ) then
    Begin
      inc(LudicCnt);
      with plL^[LudicCnt] do
      Begin
        dNum := n;
        dCnt := n;
      end;
      IF (LudicCnt >= High(LL)) then
        BREAK;
    end;
  until false;
end;

procedure  firstN(var Ll:tLudicList;cnt: NativeUint);
var
  i : NativeInt;
Begin
  writeln('First ',cnt,' ludic numbers:');
  For i := 0 to cnt-2 do
    write(Ll[i].dNum,',');
  writeln(Ll[cnt-1].dNum);
end;

procedure triples(var Ll:tLudicList;max: NativeUint);
var
  i,
  chk : NativeUint;
Begin
  // special case 1,3,7
  writeln('Ludic triples below ',max);
  write('(',ll[0].dNum,',',ll[2].dNum,',',ll[4].dNum,') ');

  For i := 1 to High(Ll) do
  Begin
    chk := ll[i].dNum;
    If chk> max then
      break;
    If (ll[i+2].dNum = chk+6) AND (ll[i+1].dNum = chk+2) then
      write('(',ll[i].dNum,',',ll[i+1].dNum,',',ll[i+2].dNum,') ');
  end;
  writeln;
  writeln;
end;

procedure LastLucid(var Ll:tLudicList;start,cnt: NativeUint);
var
  limit,i : NativeUint;
Begin
  dec(start);
  limit := high(Ll);
  IF cnt >= limit then
    cnt := limit;
  if start+cnt >limit then
    start := limit-cnt;
  writeln(Start+1,'.th to ',Start+cnt+1,'.th ludic number');
  For i := 0 to cnt-1 do
    write(Ll[i+start].dNum,',');
  writeln(Ll[start+cnt].dNum);
  writeln;
end;

function CountLudic(var Ll:tLudicList;Limit: NativeUint):NativeUint;
var
  i,res : NativeUint;
Begin
  res := 0;
  For i := 0 to High(Ll) do begin
    IF Ll[i].dnum <= Limit then
      inc(res)
    else
      BREAK;
  CountLudic:= res;
end;

end;
var
  LudicList : tLudicList;
BEGIN
  setlength(LudicList,maxLudicCnt);
  CreateLudicList(LudicList);
  firstN(LudicList,25);
  writeln('There are ',CountLudic(LudicList,1000),' ludic numbers below 1000');
  LastLucid(LudicList,2000,5);
  LastLucid(LudicList,maxLudicCnt,5);
  triples(LudicList,250);//all-> (LudicList,LudicList[High(LudicList)].dNum);
END.
Output:
First 25 ludic numbers:1,2,3,5,7,11,13,17,23,25,29,37,41,43,47,53,61,67,71,77,83,89,91,97,107
There are 142 ludic numbers below 1000
2000.th to 2005.th ludic number
21475,21481,21487,21493,21503,21511

99995.th to 100000.th ludic number
1561243,1561291,1561301,1561307,1561313,1561333

Ludic triples below 250
(1,3,7) (5,7,11) (11,13,17) (23,25,29) (41,43,47) (173,175,179) (221,223,227) (233,235,239)

real  0m2.921s 

Using an array of byte, each containing the distance to the next ludic number. 64-Bit needs only ~ 60% runtime of 32-Bit. Three times slower than the Version 1. Much space left for improvements, like memorizing the count of ludics of intervals of size 1024 or so, to do bigger steps.Something like skiplist.

program ludic;
{$IFDEF FPC}{$MODE DELPHI}{$ELSE}{$APPTYPE CONSOLE}{$ENDIF}
uses
  sysutils;
const
  MAXNUM =21511;// > 1
  //1561333;-> 100000 ludic numbers
  //1561243,1561291,1561301,1561307,1561313,1561333
type
  tarrLudic = array of byte;
  tLudics = array of LongWord;

var
  Ludiclst : tarrLudic;

procedure Firsttwentyfive;
var
  i,actLudic : NativeInt;
Begin
  writeln('First 25 ludic numbers');
  actLudic:= 1;
  For i := 1 to 25 do
  Begin
    write(actLudic:3,',');
    inc(actLudic,Ludiclst[actLudic]);
    IF i MOD 5 = 0 then
      writeln(#8#32);
  end;
  writeln;
end;

procedure CountBelowOneThousand;
var
  cnt,actLudic : NativeInt;
Begin
  write('Count of ludic numbers below 1000 = ');
  actLudic:= 1;
  cnt := 1;
  while actLudic <= 1000 do
  Begin
    inc(actLudic,Ludiclst[actLudic]);
    inc(cnt);
  end;
  dec(cnt);
  writeln(cnt);writeln;
end;

procedure Show2000til2005;
var
  cnt,actLudic : NativeInt;
Begin
  writeln('ludic number #2000 to #2005');
  actLudic:= 1;
  cnt := 1;
  while cnt < 2000 do
  Begin
    inc(actLudic,Ludiclst[actLudic]);
    inc(cnt);
  end;
  while cnt < 2005 do
  Begin
    write(actLudic,',');
    inc(actLudic,Ludiclst[actLudic]);
    inc(cnt);
  end;
  writeln(actLudic);writeln;
end;

procedure ShowTriplets;
var
  actLudic,lastDelta : NativeInt;
Begin
  writeln('ludic numbers triplets below 250');
  actLudic:= 1;
  while actLudic < 250-5 do
  Begin
    IF (Ludiclst[actLudic]   <> 0) AND
       (Ludiclst[actLudic+2] <> 0) AND
       (Ludiclst[actLudic+6] <> 0) then
      writeln('{',actLudic,'|',actLudic+2,'|',actLudic+6,'} ');
    inc(actLudic);
  end;
  writeln;
end;

procedure CheckMaxdist;
var
  actLudic,Delta,MaxDelta : NativeInt;
Begin
  MaxDelta := 0;
  actLudic:= 1;
  repeat
    delta := Ludiclst[actLudic];
    inc(actLudic,delta);
    IF MAxDelta<delta then
       MAxDelta:= delta;
  until actLudic>= MAXNUM;
  writeln('MaxDist ',MAxDelta);writeln;
end;

function GetLudics:tLudics;
//Array of byte containing the distance to next ludic number
//eliminated numbers are set to 0
var
  i,actLudic,actcnt,delta,actPos,lastPos,ludicCnt: NativeInt;
Begin
  setlength(Ludiclst,MAXNUM+1);
  For i := MAXNUM downto 0 do
    Ludiclst[i]:= 1;
  actLudic := 1;
  ludicCnt := 1;

  repeat
    inc(actLudic,Ludiclst[actLudic]);
    IF actLudic> MAXNUM then
      BREAK;
    inc(ludicCnt);
    actPos := actLudic;
    actcnt := 0;
    // Only if there are enough ludics left
    IF MaxNum-ludicCnt-actPos > actPos then
    Begin
    //eliminate every element in actLudic-distance
      //delta so i can set Ludiclst[actpos] to zero
      delta := Ludiclst[actpos];
      repeat
        lastPos := actPos;
        inc(actpos,delta);
        if actPos>=MAXNUM then
          BREAK;
        delta := Ludiclst[actpos];
        inc(actcnt);
        IF actcnt= actLudic then
        Begin
          inc(Ludiclst[LastPos],delta);
          //mark as not ludic
          Ludiclst[actpos] := 0;
          actcnt := 0;
        end;
      until false;
    end;
  until false;
  writeln(ludicCnt,' ludic numbers upto ',MAXNUM,#13#10);
end;

BEGIN
  GetLudics;
  CheckMaxdist;
  Firsttwentyfive;CountBelowOneThousand;Show2000til2005;ShowTriplets ;
  setlength(Ludiclst,0)
END.
Output:
2005 ludic numbers upto 21511

MaxDist 56

First 25 ludic numbers
  1,  2,  3,  5,  7 
 11, 13, 17, 23, 25 
 29, 37, 41, 43, 47 
 53, 61, 67, 71, 77 
 83, 89, 91, 97,107 

Count of ludic numbers below 1000 = 142

ludic number #2000 to #2005
21475,21481,21487,21493,21503,21511

ludic numbers triplets below 250
{1|3|7} 
{5|7|11} 
{11|13|17} 
{23|25|29} 
{41|43|47} 
{173|175|179} 
{221|223|227} 
{233|235|239} 
real    0m0.003s

100000 ludic numbers upto 1561334
...
real    0m8.438s

Perl

The "ludic" subroutine caches the longest generated sequence so far. It also generates the candidates only if no candidates remain.

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

{   my @ludic = (1);
    my $max = 3;
    my @candidates;

    sub sieve {
        my $l = shift;
        for (my $i = 0; $i <= $#candidates; $i += $l) {
            splice @candidates, $i, 1;
        }
    }

    sub ludic {
        my ($type, $n) = @_;
        die "Arg0 Type must be 'count' or 'max'\n"
             unless grep $_ eq $type, qw( count max );
        die "Arg1 Number must be > 0\n" if 0 >= $n;

        return (@ludic[ 0 .. $n - 1 ]) if 'count' eq $type and @ludic >= $n;

        return (grep $_ <= $n, @ludic) if 'max'   eq $type and $ludic[-1] >= $n;

        while (1) {
            if (@candidates) {
                last if ('max' eq $type and $candidates[0] > $n)
                     or ($n == @ludic);

                push @ludic, $candidates[0];
                sieve($ludic[-1] - 1);

            } else {
                $max *= 2;
                @candidates = 2 .. $max;
                for my $l (@ludic) {
                    sieve($l - 1) unless 1 == $l;
                }
            }
        }
        return (@ludic)
    }

}

my @triplet;
my %ludic;
undef @ludic{ ludic(max => 250) };
for my $i (keys %ludic) {
    push @triplet, $i if exists $ludic{ $i + 2 } and exists $ludic { $i + 6 };
}

say 'First 25:       ', join ' ', ludic(count => 25);
say 'Count < 1000:   ', scalar ludic(max => 1000);
say '2000..2005th:   ', join ' ', (ludic(count => 2005))[1999 .. 2004];
say 'triplets < 250: ', join ' ',
                        map { '(' . join(' ',$_, $_ + 2, $_ + 6) . ')' }
                        sort { $a <=> $b } @triplet;
Output:
First 25:       1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107
Count < 1000:   142
2000..2005th:   21475 21481 21487 21493 21503 21511
triplets < 250: (1 3 7) (5 7 11) (11 13 17) (23 25 29) (41 43 47) (173 175 179) (221 223 227) (233 235 239)

Phix

Translation of: Fortran
constant LUMAX = 25000
sequence ludic = repeat(1,LUMAX)
integer n
for i=2 to LUMAX/2 do
    if ludic[i] then
        n = 0
        for j=i+1 to LUMAX do
            n += ludic[j]
            if n=i then
                ludic[j] = 0
                n = 0
            end if
        end for
    end if
end for
 
sequence s = {}
for i=1 to LUMAX do
    if ludic[i] then
        s &= i
        if length(s)=25 then exit end if
    end if
end for
printf(1,"First 25 Ludic numbers: %s\n",{sprint(s)})
printf(1,"Ludic numbers below 1000: %d\n",{sum(ludic[1..1000])})
s = {}
n = 0
for i=1 to LUMAX do
    if ludic[i] then
        n += 1
        if n>=2000 then
            s &= i
            if n=2005 then exit end if
        end if
    end if
end for
printf(1,"Ludic numbers 2000 to 2005: %s\n",{sprint(s)})
s = {}
for i=1 to 243 do
    if ludic[i] and ludic[i+2] and ludic[i+6] then
       s = append(s,{i,i+2,i+6})
    end if  
end for
printf(1,"There are %d Ludic triplets below 250: %s\n",{length(s),sprint(s)})
Output:
First 25 Ludic numbers: {1,2,3,5,7,11,13,17,23,25,29,37,41,43,47,53,61,67,71,77,83,89,91,97,107}
Ludic numbers below 1000: 142
Ludic numbers 2000 to 2005: {21475,21481,21487,21493,21503,21511}
There are 8 Ludic triplets below 250: {{1,3,7},{5,7,11},{11,13,17},{23,25,29},{41,43,47},{173,175,179},{221,223,227},{233,235,239}}

Picat

Recursion

ludic(N) = Ludic =>
  ludic(2..N, [1], Ludic).
ludic([], Ludic0, Ludic) => 
  Ludic = Ludic0.reverse().
ludic(T, Ludic0, Ludic) =>
  T2 = ludic_keep(T),
  ludic(T2,[T[1]|Ludic0],Ludic).

% which elements to keep
ludic_keep([]) = [].
ludic_keep([H|List]) = Ludic =>
  ludic_keep(H,1,List,[],Ludic).

ludic_keep(_H,_C,[],Ludic0,Ludic) ?=>
  Ludic = Ludic0.reverse().
ludic_keep(H,C,[H1|T],Ludic0,Ludic) =>
  (
  C mod H > 0 ->
    ludic_keep(H,C+1,T,[H1|Ludic0],Ludic)
  ;
   ludic_keep(H,C+1,T,Ludic0,Ludic)
  ).

Imperative approach

ludic2(N) = Ludic =>
  A = 1..N,
  Ludic = [1],
  A := delete(A, 1),
  while(A.length > 0)
    T = A[1],
    Ludic := Ludic ++ [T],
    A := delete(A,T),
    A := [A[J] : J in 1..A.length, J mod T > 0]
  end.

Test

The recursive variant is about 10 times faster than the imperative.

go =>
 time(check(ludic)),
 time(check(ludic2)),
 nl.

check(LudicFunc) =>
  println(ludicFunc=LudicFunc),

  Ludic1000 = apply(LudicFunc,1000),

  % first 25
  println(first_25=Ludic1000[1..25]),

  % below 1000
  println(num_below_1000=Ludic1000.length),
  
  % 2000..2005
  Ludic22000 = apply(LudicFunc,22000),
  println(len_22000=Ludic22000.length),
  println(ludic_2000_2005=[Ludic22000[I] : I in 2000..2005]),

  % Triplets
  Ludic2500 = apply(LudicFunc,2500),
  Triplets=[[N,N+2,N+6] : N in 1..Ludic2500.length,
                                  membchk(N,Ludic2500),
                                  membchk(N+2,Ludic2500),
                                  membchk(N+6,Ludic2500)],
  foreach(Triplet in Triplets)
    println(Triplet)
  end,
  nl.
Output:
ludicFunc = ludic
first_25 = [1,2,3,5,7,11,13,17,23,25,29,37,41,43,47,53,61,67,71,77,83,89,91,97,107]
num_below_1000 = 142
len_22000 = 2042
ludic_2000_2005 = [21475,21481,21487,21493,21503,21511]
[1,3,7]
[5,7,11]
[11,13,17]
[23,25,29]
[41,43,47]
[173,175,179]
[221,223,227]
[233,235,239]

CPU time 0.288 seconds.

ludicFunc = ludic2
first_25 = [1,2,3,5,7,11,13,17,23,25,29,37,41,43,47,53,61,67,71,77,83,89,91,97,107]
num_below_1000 = 142
len_22000 = 2042
ludic_2000_2005 = [21475,21481,21487,21493,21503,21511]
[1,3,7]
[5,7,11]
[11,13,17]
[23,25,29]
[41,43,47]
[173,175,179]
[221,223,227]
[233,235,239]

CPU time 2.835 seconds.

PicoLisp

(de drop (Lst)
   (let N (car Lst)
      (make
         (for (I . X) (cdr Lst)
            (unless (=0 (% I N)) (link X)) ) ) ) )
 
(de comb (M Lst)
   (cond
      ((=0 M) '(NIL))
      ((not Lst))
      (T
         (conc
            (mapcar
               '((Y) (cons (car Lst) Y))
               (comb (dec M) (cdr Lst)) )
            (comb M (cdr Lst)) ) ) ) )
           
(de ludic (N)
   (let Ludic (range 1 100000)
      (make
         (link (pop 'Ludic))
         (do (dec N)
            (link (car Ludic))
            (setq Ludic (drop Ludic)) ) ) ) )
 
(let L (ludic 2005)
   (println (head 25 L))
   (println (cnt '((X) (< X 1000)) L))
   (println (tail 6 L))
   (println
      (filter
         '((Lst)
            (and
              (= (+ 2 (car Lst)) (cadr Lst))
              (= (+ 6 (car Lst)) (caddr Lst)) ) )
         (comb
            3
            (filter '((X) (< X 250)) L) ) ) ) )
 
(bye)
Output:

(1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107) 142 (21475 21481 21487 21493 21503 21511)

((1 3 7) (5 7 11) (11 13 17) (23 25 29) (41 43 47) (173 175 179) (221 223 227) (233 235 239))

PL/I

Ludic_numbers: procedure options (main);                /* 18 April 2014 */
   declare V(2:22000) fixed, L(2200) fixed;
   declare (step, i, j, k, n) fixed binary;

Ludic: procedure;
   n = hbound(V,1); k = 1; L(1) = 1;
   do i = 2 to n; V(i) = i; end;

   do forever;
      
      k = k + 1; L(k), step = V(2);

      do i = 2 to n by step;
         V(i) = 0;
      end;
      call compress;
      if L(k) >= 21511 then leave;
   end;

   put skip list ('The first 25 Ludic numbers are:');
   put skip edit ( (L(i) do i = 1 to 25) ) (F(4));

   k = 0;
   do i = 1 by 1;
      if L(i) < 1000 then k = k + 1; else leave;
   end;

   put skip list ('There are ' || trim(k) || ' Ludic numbers < 1000');
   put skip list ('Six Ludic numbers from the 2000-th:');
   put skip edit ( (L(i) do i = 2000 to 2005) ) (f(7));
   /* Triples are values of the form x, x+2, x+6 */
   put skip list ('Triples are:');
   put skip;
   i = 1;
   put edit ('(', L(1), L(3), L(5), ') ' ) (A, 3 F(4), A);
   do i = 1 by 1 while (L(i+2) <= 250);
      if (L(i) = L(i+1) - 2) & (L(i) = L(i+2) - 6) then
         put edit ('(', L(i), L(i+1), L(i+2), ') ' ) (A, 3 F(4), A);
   end;

compress: procedure;
   j = 2;
   do i = 2 to n;
      if V(i) ^= 0 then do; V(j) = V(i); j = j + 1; end;
   end;
   n = j-1;
end compress;

end Ludic;

call Ludic;

end Ludic_numbers;

Output:

The first 25 Ludic numbers are: 
   1   2   3   5   7  11  13  17  23  25  29  37  41  43  47
  53  61  67  71  77  83  89  91  97 107
There are 142 Ludic numbers < 1000 
Six Ludic numbers from the 2000-th: 
  21475  21481  21487  21493  21503  21511
Triples are: 
(   1   3  7) (   5   7  11) (  11  13  17) (  23  25  29) (  41  43  47)
( 173 175 179) ( 221 223 227) ( 233 235 239)

PL/SQL

SET SERVEROUTPUT ON
DECLARE
  c_limit CONSTANT PLS_INTEGER := 25000;
  TYPE t_nums IS TABLE OF PLS_INTEGER INDEX BY PLS_INTEGER;
  v_nums t_nums;
  v_ludic t_nums;
  v_count_ludic PLS_INTEGER;
  v_count_pos PLS_INTEGER;
  v_pos PLS_INTEGER;
  v_next_ludic PLS_INTEGER;

  FUNCTION is_ludic(p_num PLS_INTEGER) RETURN BOOLEAN IS
  BEGIN
    FOR i IN 1..v_ludic.COUNT LOOP
      EXIT WHEN v_ludic(i) > p_num;
      IF v_ludic(i) = p_num THEN
        RETURN TRUE;
      END IF;
    END LOOP;
    RETURN FALSE;
  END;

BEGIN
  FOR i IN 1..c_limit LOOP
    v_nums(i) := i;
  END LOOP;

  v_count_ludic := 1;
  v_next_ludic := 1;
  v_ludic(v_count_ludic) := v_next_ludic;
  v_nums.DELETE(1);

  WHILE v_nums.COUNT > 0 LOOP
    v_pos := v_nums.FIRST;
    v_next_ludic := v_nums(v_pos);
    v_count_ludic := v_count_ludic + 1;
    v_ludic(v_count_ludic) := v_next_ludic;
    v_count_pos := 0;
    WHILE v_pos IS NOT NULL LOOP
      IF MOD(v_count_pos, v_next_ludic) = 0 THEN
        v_nums.DELETE(v_pos);
      END IF;
      v_pos := v_nums.NEXT(v_pos);
      v_count_pos := v_count_pos + 1;
    END LOOP;
  END LOOP;

  dbms_output.put_line('Generate and show here the first 25 ludic numbers.');
  FOR i IN 1..25 LOOP
    dbms_output.put(v_ludic(i) || ' ');
  END LOOP;
  dbms_output.put_line('');

  dbms_output.put_line('How many ludic numbers are there less than or equal to 1000?');
  v_count_ludic := 0;
  FOR i IN 1..v_ludic.COUNT LOOP
    EXIT WHEN v_ludic(i) > 1000;
    v_count_ludic := v_count_ludic + 1;
  END LOOP;
  dbms_output.put_line(v_count_ludic);

  dbms_output.put_line('Show the 2000..2005''th ludic numbers.');
  FOR i IN 2000..2005 LOOP
    dbms_output.put(v_ludic(i) || ' ');
  END LOOP;
  dbms_output.put_line('');

  dbms_output.put_line('A triplet is any three numbers x, x + 2, x + 6 where all three numbers are also ludic numbers.');
  dbms_output.put_line('Show all triplets of ludic numbers < 250 (Stretch goal)');
  FOR i IN 1..v_ludic.COUNT LOOP
    EXIT WHEN (v_ludic(i)+6) >= 250;
    IF is_ludic(v_ludic(i)+2) AND is_ludic(v_ludic(i)+6) THEN
      dbms_output.put_line(v_ludic(i) || ', ' || (v_ludic(i)+2) || ', ' || (v_ludic(i)+6));
    END IF;
  END LOOP;

END;
/
Output:
Generate and show here the first 25 ludic numbers.
1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107 
How many ludic numbers are there less than or equal to 1000?
142
Show the 2000..2005'th ludic numbers.
21475 21481 21487 21493 21503 21511 
A triplet is any three numbers x, x + 2, x + 6 where all three numbers are also ludic numbers.
Show all triplets of ludic numbers < 250 (Stretch goal)
1, 3, 7
5, 7, 11
11, 13, 17
23, 25, 29
41, 43, 47
173, 175, 179
221, 223, 227
233, 235, 239

PowerShell

Works with: PowerShell version 2
#  Start with a pool large enough to meet the requirements
$Pool = [System.Collections.ArrayList]( 2..22000 )
 
#  Start with 1, because it's grandfathered in
$Ludic = @( 1 )
 
#  While the size of the pool is still larger than the next Ludic number...
While ( $Pool.Count -gt $Pool[0] )
    {
    #  Add the next Ludic number to the list
    $Ludic += $Pool[0]
 
    #  Remove from the pool all entries whose index is a multiple of the next Ludic number
    [math]::Truncate( ( $Pool.Count - 1 )/ $Pool[0])..0 | ForEach { $Pool.RemoveAt( $_ * $Pool[0] ) }
    }
 
#  Add the rest of the numbers in the pool to the list of Ludic numbers
$Ludic += $Pool.ToArray()
#  Display the first 25 Ludic numbers
$Ludic[0..24] -join ", "
''
 
#  Display the count of all Ludic numbers under 1000
$Ludic.Where{ $_ -le 1000 }.Count
''
 
#  Display the 2000th through the 2005th Ludic number
$Ludic[1999..2004] -join ", "
''
 
#  Display all Ludic triplets less than 250
$TripletStart = $Ludic.Where{ $_ -lt 244 -and ( $_ + 2 ) -in $Ludic -and ( $_ + 6 ) -in $Ludic }
$TripletStart.ForEach{ $_, ( $_ + 2 ), ( $_ + 6 ) -join ", " }
Output:
1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107

142

21475, 21481, 21487, 21493, 21503, 21511

1, 3, 7
5, 7, 11
11, 13, 17
23, 25, 29
41, 43, 47
173, 175, 179
221, 223, 227
233, 235, 239

Prolog

Simple, straightforward implementation

% John Devou: 26-Nov-2021

d(_,_,[],[]).
d(N,N,[_|Xs],Rs):- d(N,1,Xs,Rs).
d(N,M,[X|Xs],[X|Rs]):- M < N, M_ is M+1, d(N,M_,Xs,Rs).

l([],[]).
l([X|Xs],[X|Rs]):- d(X,1,Xs,Ys), l(Ys,Rs).

% g(N,L):- generate in L a list with Ludic numbers up to N

g(N,[1|X]):- numlist(2,N,L), l(L,X).

s(0,Xs,[],Xs).
s(N,[X|Xs],[X|Ls],Rs):- N > 0, M is N-1, s(M,Xs,Ls,Rs).

t([X,Y,Z|_],[X,Y,Z]):- Y =:= X+2, Z =:= X+6.
t([_,Y,Z|Xs],R):- t([Y,Z|Xs],R).

% tasks

t1:- g(500,L), s(25,L,X,_), write(X), !.
t2:- g(1000,L), length(L,X), write(X), !.
t3:- g(22000,L), s(1999,L,_,R), s(6,R,X,_), write(X), !.
t4:- g(249,L), findall(A, t(L,A), X), write(X), !.
Output:
?- t1.   
[1,2,3,5,7,11,13,17,23,25,29,37,41,43,47,53,61,67,71,77,83,89,91,97,107]
true.

?- t2.   
142
true.

?- t3.
[21475,21481,21487,21493,21503,21511]
true.

?- t4.
[[5,7,11],[11,13,17],[23,25,29],[41,43,47],[173,175,179],[221,223,227],[233,235,239]]
true.

PureBasic

EnableExplicit
If Not OpenConsole() : End 1 : EndIf

#NMAX=25000

Dim ludic.b(#NMAX)
FillMemory(@ludic(0),SizeOf(Byte)*#NMAX,#True,#PB_Byte)

Define.i  i,j,n,c1,c2
Define    r1$,r2$,r3$,r4$

For i=2 To Int(#NMAX/2)
  If ludic(i)
    n=0
    For j=i+1 To #NMAX
      If ludic(j) : n+1 : EndIf
      If n=i : ludic(j)=#False : n=0 : EndIf
    Next j
  EndIf
Next i

n=0 : c1=0 : c2=0
For i=1 To #NMAX
  If ludic(i) And n<25 : n+1 : r1$+Str(i)+" " : EndIf  
  If i<=1000 : c1+Bool(ludic(i)) : EndIf  
  c2+Bool(ludic(i))
  If c2>=2000 And c2<=2005 And ludic(i) : r3$+Str(i)+" " : EndIf
  If i<243 And ludic(i) And ludic(i+2) And ludic(i+6)
    r4$+"["+Str(i)+" "+Str(i+2)+" "+Str(i+6)+"] "
  EndIf  
Next
r2$=Str(c1)

PrintN("First 25 Ludic numbers: "     +r1$)
PrintN("Ludic numbers below 1000: "   +r2$)
PrintN("Ludic numbers 2000 to 2005: " +r3$)
PrintN("Ludic Triplets below 250: "   +r4$)
Input()
End
Output:
First 25 Ludic numbers: 1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107 
Ludic numbers below 1000: 142
Ludic numbers 2000 to 2005: 21475 21481 21487 21493 21503 21511 
Ludic Triplets below 250: [1 3 7] [5 7 11] [11 13 17] [23 25 29] [41 43 47] [173 175 179] [221 223 227] [233 235 239] 

Python

Python: Fast

def ludic(nmax=100000):
    yield 1
    lst = list(range(2, nmax + 1))
    while lst:
        yield lst[0]
        del lst[::lst[0]]

ludics = [l for l in ludic()]

print('First 25 ludic primes:')
print(ludics[:25])
print("\nThere are %i ludic numbers <= 1000"
      % sum(1 for l in ludics if l <= 1000)) 
print("\n2000'th..2005'th ludic primes:")
print(ludics[2000-1: 2005])

n = 250
triplets = [(x, x+2, x+6)
            for x in ludics
            if x+6 < n and x+2 in ludics and x+6 in ludics]
print('\nThere are %i triplets less than %i:\n  %r'
      % (len(triplets), n, triplets))
Output:
First 25 ludic primes:
[1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107]

There are 142 ludic numbers <= 1000

2000'th..2005'th ludic primes:
[21475, 21481, 21487, 21493, 21503, 21511]

There are 8 triplets less than 250:
  [(1, 3, 7), (5, 7, 11), (11, 13, 17), (23, 25, 29), (41, 43, 47), (173, 175, 179), (221, 223, 227), (233, 235, 239)]

Python: No set maximum

The following version of function ludic will return ludic numbers until reaching system limits. It is less efficient than the fast version as all lucid numbers so far are cached; on exhausting the current lst a new list of twice the size is created and the previous deletions applied before continuing.

def ludic(nmax=64):
    yield 1
    taken = []
    while True:
        lst, nmax = list(range(2, nmax + 1)), nmax * 2
        for t in taken:
            del lst[::t]
        while lst:
            t = lst[0]
            taken.append(t)
            yield t
            del lst[::t]

Output is the same as for the fast version.

Python: lazy streaming generator

The following streaming version of function ludic also returns ludic numbers until reaching system limits. Instead of creating a bounded table and deleting elements, it uses the insight that after each iteration the remaining numbers are shuffled left, modifying their indices in a regular way. Reversing this process tracks the k'th ludic number in the final list back to its position in the initial list of integers, and hence determines its value without any need to build the table. The only storage requirement is for the list of numbers found so far.
Based on the similar algorithm for lucky numbers at https://oeis.org/A000959/a000959.txt.
Function triplets wraps ludic and uses a similar stream-filtering approach to find triplets.

def ludic():
    yield 1
    ludics = []
    while True:
        k = 0 
        for j in reversed(ludics):
            k = (k*j)//(j-1) + 1
        ludics.append(k+2) 
        yield k+2
def triplets():
    a, b, c, d = 0, 0, 0, 0
    for k in ludic():
        if k-4 in (b, c, d) and k-6 in (a, b, c):
            yield k-6, k-4, k
        a, b, c, d = b, c, d, k

first_25 = [k for i, k in zip(range(25), gen_ludic())]
print(f'First 25 ludic numbers: {first_25}')
count = 0
for k in gen_ludic():
    if k > 1000:
        break
    count += 1
print(f'Number of ludic numbers <= 1000: {count}')
it = iter(gen_ludic())
for i in range(1999):
    next(it)
ludic2000 = [next(it) for i in range(6)]
print(f'Ludic numbers 2000..2005: {ludic2000}')    
   
print('Ludic triplets < 250:')
for a, b, c in triplets():
    if c >= 250:
        break
    print(f'[{a}, {b}, {c}]')
Output:
First 25 ludic numbers: [1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107]
Number of ludic numbers <= 1000: 142
Ludic numbers 2000..2005: [21475, 21481, 21487, 21493, 21503, 21511]
Ludic triplets < 250:
[1, 3, 7]
[5, 7, 11]
[11, 13, 17]
[23, 25, 29]
[41, 43, 47]
[173, 175, 179]
[221, 223, 227]
[233, 235, 239]

Quackery

  [ 0 over of
    swap times
      [ i 1+ swap i poke ]
    1 split
    [ dup 0 peek
      rot over join unrot
      over size over > while
      1 - temp put
      [] swap
      [ behead drop
        temp share split
        dip join
        dup [] = until ]
      drop temp release
      again ]
      drop behead drop join ] is ludic ( n --> [ )

  999 ludic
  say "First 25 ludic numbers: "
  dup 25 split drop echo
  cr cr
  say "There are "
  size echo
  say " ludic numbers less than 1000."
  cr cr
  25000 ludic
  say "Ludic numbers 2000 to 2005: "
  1999 split nip 6 split drop echo
Output:
First 25 ludic numbers: [ 1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107 ]

There are 142 ludic numbers less than 1000.

Ludic numbers 2000 to 2005: [ 21475 21481 21487 21493 21503 21511 ]

Racket

#lang racket
(define lucid-sieve-size 25000) ; this should be enough to do me!
(define lucid?
  (let ((lucid-bytes-sieve
         (delay
           (define sieve-bytes (make-bytes lucid-sieve-size 1))       
           (bytes-set! sieve-bytes 0 0) ; not a lucid number
           (define (sieve-pass L)
             (let loop ((idx (add1 L)) (skip (sub1 L)))
               (cond
                 [(= idx lucid-sieve-size)
                  (for/first ((rv (in-range (add1 L) lucid-sieve-size))
                              #:unless (zero? (bytes-ref sieve-bytes rv))) rv)]
                 [(zero? (bytes-ref sieve-bytes idx))
                  (loop (add1 idx) skip)]
                 [(= skip 0)
                  (bytes-set! sieve-bytes idx 0)
                  (loop (add1 idx) (sub1 L))]
                 [else (loop (add1 idx) (sub1 skip))])))
           (let loop ((l 2))
             (when l (loop (sieve-pass l))))
           sieve-bytes)))
    
    (λ (n) (= 1 (bytes-ref (force lucid-bytes-sieve) n)))))

(define (dnl . things) (for-each displayln things))

(dnl
 "Generate and show here the first 25 ludic numbers."
 (for/list ((_ 25) (l (sequence-filter lucid? (in-naturals)))) l)
 "How many ludic numbers are there less than or equal to 1000?"
 (for/sum ((n 1001) #:when (lucid? n)) 1)
 "Show the 2000..2005'th ludic numbers."
 (for/list ((i 2006) (l (sequence-filter lucid? (in-naturals))) #:when (>= i 2000)) l)
 #<<EOS
A triplet is any three numbers x, x + 2, x + 6 where all three numbers are
also ludic numbers. Show all triplets of ludic numbers < 250 (Stretch goal)
EOS
 (for/list ((x (in-range 250)) #:when (and (lucid? x) (lucid? (+ x 2)) (lucid? (+ x 6))))
   (list x (+ x 2) (+ x 6))))
Output:
Generate and show here the first 25 ludic numbers.
(1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107)
How many ludic numbers are there less than or equal to 1000?
142
Show the 2000..2005'th ludic numbers.
(21481 21487 21493 21503 21511 21523)
A triplet is any three numbers x, x + 2, x + 6 where all three numbers are
also ludic numbers. Show all triplets of ludic numbers < 250 (Stretch goal)
((1 3 7) (5 7 11) (11 13 17) (23 25 29) (41 43 47) (173 175 179) (221 223 227) (233 235 239))
cpu time: 18753 real time: 18766 gc time: 80

Raku

(formerly Perl 6)

Works with: rakudo version 2015-09-18

This implementation has no arbitrary upper limit, since it can keep adding new rotors on the fly. It just gets slower and slower instead... :-)

constant @ludic = gather {
        my @taken = take 1;
        my @rotor;
 
        for 2..* -> $i {
            loop (my $j = 0; $j < @rotor; $j++) {
                --@rotor[$j] or last;
            }
            if $j < @rotor {
                @rotor[$j] = @taken[$j+1];
            }
            else {
                push @taken, take $i;
                push @rotor, @taken[$j+1];
            }
        }
    }
 
say @ludic[^25];
say "Number of Ludic numbers <= 1000: ", +(@ludic ...^ * > 1000);
say "Ludic numbers 2000..2005: ", @ludic[1999..2004];
 
my \l250 = set @ludic ...^ * > 250;
say "Ludic triples < 250: ", gather
    for l250.keys.sort -> $a {
        my $b = $a + 2;
        my $c = $a + 6;
        take "<$a $b $c>" if $bl250 and $cl250;
    }
Output:
(1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107)
Number of Ludic numbers <= 1000: 142
Ludic numbers 2000..2005: (21475 21481 21487 21493 21503 21511)
Ludic triples < 250: (<1 3 7> <5 7 11> <11 13 17> <23 25 29> <41 43 47> <173 175 179> <221 223 227> <233 235 239>)

REXX

/*REXX program gens/shows (a range of)  ludic numbers,  or a count when a range is used.*/
parse arg N count bot top triples .              /*obtain optional arguments from the CL*/
if       N=='' |       N=="," then       N=   25 /*Not specified?  Then use the default.*/
if   count=='' |   count=="," then   count= 1000 /* "      "         "   "   "     "    */
if     bot=='' |     bot=="," then     bot= 2000 /* "      "         "   "   "     "    */
if     top=='' |     top=="," then     top= 2005 /* "      "         "   "   "     "    */
if triples=='' | triples=="," then triples=  249 /* "      "         "   "   "     "    */
#= 0                                             /*the number of ludic numbers (so far).*/
$= ludic( max(N, count, bot, top, triples) )                /*generate enough ludic nums*/
say 'The first '   N   " ludic numbers: "   subword($,1,25) /*display 1st  N  ludic nums*/
               do j=1  until word($, j) > count             /*search up to a specific #.*/
               end   /*j*/
say
say "There are "          j - 1           ' ludic numbers that are  ≤ '            count
say
say "The "  bot  '───►'     top     ' (inclusive)  ludic numbers are: '    subword($, bot)
@=                                               /*list of ludic triples found (so far).*/
     do j=1  for words($)
     _= word($, j)                               /*it is known that ludic   _   exists. */
     if _>=triples  then leave                   /*only process up to a specific number.*/
     if wordpos(_+2, $)==0 | wordpos(_+6, $)==0  then iterate    /*Not triple?  Skip it.*/
     #= # + 1                                    /*bump the triple counter.             */
     @= @ '◄'_  _+2  _+6"► "                     /*append the newly found triple ──►  @ */
     end   /*j*/
say
if @==''  then  say  'From 1──►'triples", no triples found."
          else  say  'From 1──►'triples", "     #     ' triples found:'      @
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
ludic: procedure; parse arg m,,@;    $= 1 2      /*$≡ludic numbers superset;  @≡sequence*/
           do j=3  by 2  to  m*15;   @= @ j      /*construct an initial list of numbers.*/
           end   /*j*/
       @= @' ';                    n= words(@)   /*append a blank to the number sequence*/
           do while n\==0;         f= word(@, 1) /*examine the first word in the @ list.*/
           $= $ f                                /*add the word to the  $  list.        */
              do d=1  by f  while d<=n;   n= n-1 /*use 1st number, elide all occurrences*/
              @= changestr(' 'word(@, d)" ",  @,  ' . ')     /*cross─out a number in  @ */
              end   /*d*/                        /* [↑]  done eliding the "1st" number. */
           @= translate(@, , .)                  /*change dots to blanks; count numbers.*/
           end      /*while*/                    /* [↑]  done eliding ludic numbers.    */
       return subword($, 1, m)                   /*return a  range  of  ludic  numbers. */

Some older REXXes don't have a   changestr   BIF,   so one is included here   ──►   CHANGESTR.REX.

output   using the default values for input:

The first  25  ludic numbers:  1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107

There are  142  ludic numbers that are  ≤  1000

The  2000 ───► 2005  (inclusive)  ludic numbers are:  21475 21481 21487 21493 21503 21511

From 1──►249,  8  triples found:  ◄1 3 7►  ◄5 7 11►  ◄11 13 17►  ◄23 25 29►  ◄41 43 47►  ◄173 175 179►  ◄221 223 227►  ◄233 235 239►

Ring

# Project : Ludic numbers

ludic = list(300)
resludic = []
nr = 1
for n = 1 to len(ludic)
     ludic[n] = n+1
next
see "the first 25 Ludic numbers are:" + nl
ludicnumbers(ludic)
showarray(resludic)
see nl

see "Ludic numbers below 1000: " 
ludic = list(3000)
resludic = []
for n = 1 to len(ludic)
     ludic[n] = n+1
next
ludicnumbers(ludic)
showarray2(resludic)
see nr
see nl + nl

see "the 2000..2005th Ludic numbers are:" + nl
ludic = list(60000)
resludic = []
for n = 1 to len(ludic)
     ludic[n] = n+1
next
ludicnumbers(ludic)
showarray3(resludic)

func ludicnumbers(ludic)
      for n = 1 to len(ludic)
          delludic = [] 
          for m = 1 to len(ludic) step ludic[1]
              add(delludic, m)
          next
          add(resludic, ludic[1])
          for p = len(delludic)  to 1 step -1
              del(ludic, delludic[p])
          next
      next 

func showarray(vect)
      see "[1, "
      svect = ""
      for n = 1 to 24
          svect = svect + vect[n] + ", "
      next
      svect = left(svect, len(svect) - 2)
      see svect
      see "]" + nl

func showarray2(vect)
      for n = 1 to len(vect)
          if vect[n] <= 1000
             nr = nr + 1
          ok
      next
      return nr

func showarray3(vect)
      see "["
      svect = ""
      for n = 1999 to 2004
          svect = svect + vect[n] + ", "
      next
      svect = left(svect, len(svect) - 2)
      see svect
      see "]" + nl

Output:

the first 25 Ludic numbers are:
[1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107]

Ludic numbers below 1000: 142

the 2000..2005th ludic numbers are:
[21475, 21481, 21487, 21493, 21503, 21511]

Ruby

def ludic(nmax=100000)
  Enumerator.new do |y|
    y << 1
    ary = *2..nmax
    until ary.empty?
      y << (n = ary.first)
      (0...ary.size).step(n){|i| ary[i] = nil}
      ary.compact!
    end
  end
end

puts "First 25 Ludic numbers:", ludic.first(25).to_s

puts "Ludics below 1000:", ludic(1000).count

puts "Ludic numbers 2000 to 2005:", ludic.first(2005).last(6).to_s

ludics = ludic(250).to_a
puts "Ludic triples below 250:",
     ludics.select{|x| ludics.include?(x+2) and ludics.include?(x+6)}.map{|x| [x, x+2, x+6]}.to_s
Output:
First 25 Ludic numbers:
[1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107]
Ludics below 1000:
142
Ludic numbers 2000 to 2005:
[21475, 21481, 21487, 21493, 21503, 21511]
Ludic triples below 250:
[[1, 3, 7], [5, 7, 11], [11, 13, 17], [23, 25, 29], [41, 43, 47], [173, 175, 179], [221, 223, 227], [233, 235, 239]]

Rust

const ARRAY_MAX: usize = 25_000;
const LUDIC_MAX: usize = 2100;

/// Calculates and returns the first `LUDIC_MAX` Ludic numbers.
///
/// Needs a sufficiently large `ARRAY_MAX`.
fn ludic_numbers() -> Vec<usize> {
    // The first two Ludic numbers
    let mut numbers = vec![1, 2];
    // We start the array with an immediate first removal to reduce memory usage by
    // collecting only odd numbers.
    numbers.extend((3..ARRAY_MAX).step_by(2));

    // We keep the correct Ludic numbers in place, removing the incorrect ones.
    for ludic_idx in 2..LUDIC_MAX {
        let next_ludic = numbers[ludic_idx];

        // We remove incorrect numbers by counting the indices after the correct numbers.
        // We start from zero and keep until we reach the potentially incorrect numbers.
        // Then we keep only those not divisible by the `next_ludic`.
        let mut idx = 0;
        numbers.retain(|_| {
            let keep = idx <= ludic_idx || (idx - ludic_idx) % next_ludic != 0;
            idx += 1;
            keep
        });
    }

    numbers
}

fn main() {
    let ludic_numbers = ludic_numbers();

    print!("First 25: ");
    print_n_ludics(&ludic_numbers, 25);
    println!();
    print!("Number of Ludics below 1000: ");
    print_num_ludics_upto(&ludic_numbers, 1000);
    println!();
    print!("Ludics from 2000 to 2005: ");
    print_ludics_from_to(&ludic_numbers, 2000, 2005);
    println!();
    println!("Triplets below 250: ");
    print_triplets_until(&ludic_numbers, 250);
}

/// Prints the first `n` Ludic numbers.
fn print_n_ludics(x: &[usize], n: usize) {
    println!("{:?}", &x[..n]);
}

/// Calculates how many Ludic numbers are below `max_num`.
fn print_num_ludics_upto(x: &[usize], max_num: usize) {
    let num = x.iter().take_while(|&&i| i < max_num).count();
    println!("{}", num);
}

/// Prints Ludic numbers between two numbers.
fn print_ludics_from_to(x: &[usize], from: usize, to: usize) {
    println!("{:?}", &x[from - 1..to - 1]);
}

/// Calculates triplets until a certain Ludic number.
fn triplets_below(ludics: &[usize], limit: usize) -> Vec<(usize, usize, usize)> {
    ludics
        .iter()
        .enumerate()
        .take_while(|&(_, &num)| num < limit)
        .filter_map(|(idx, &number)| {
            let triplet_2 = number + 2;
            let triplet_3 = number + 6;

            // Search for the other two triplet numbers.  We know they are larger than
            // `number` so we can give the searches lower bounds of `idx + 1` and
            // `idx + 2`.  We also know that the `n + 2` number can only ever be two
            // numbers away from the previous and the `n + 6` number can only be four
            // away (because we removed some in between).  Short circuiting and doing
            // the check more likely to fail first are also useful.
            let is_triplet = ludics[idx + 1..idx + 3].binary_search(&triplet_2).is_ok()
                && ludics[idx + 2..idx + 5].binary_search(&triplet_3).is_ok();

            if is_triplet {
                Some((number, triplet_2, triplet_3))
            } else {
                None
            }
        })
        .collect()
}

/// Prints triplets until a certain Ludic number.
fn print_triplets_until(ludics: &[usize], limit: usize) {
    for (number, triplet_2, triplet_3) in triplets_below(ludics, limit) {
        println!("{} {} {}", number, triplet_2, triplet_3);
    }
}
Output:
First 25: [1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107]

Number of Ludics below 1000: 142

Ludics from 2000 to 2005: [21475, 21481, 21487, 21493, 21503]

Triplets below 250: 
1 3 7
5 7 11
11 13 17
23 25 29
41 43 47
173 175 179
221 223 227
233 235 239

Scala

In this example, we define a function to drop every nth element from a list and use it to build a lazily evaluated list of all Ludic numbers. We then generate a lazy list of triplets and filter for the triplets of Ludic numbers.

object Ludic {
  def main(args: Array[String]): Unit = {
    println(
      s"""|First 25 Ludic Numbers: ${ludic.take(25).mkString(", ")}
          |Ludic Numbers <= 1000: ${ludic.takeWhile(_ <= 1000).size}
          |2000-2005th Ludic Numbers: ${ludic.slice(1999, 2005).mkString(", ")}
          |Triplets <= 250: ${triplets.takeWhile(_._3 <= 250).mkString(", ")}""".stripMargin)
  }
  
  def dropByN[T](lst: LazyList[T], len: Int): LazyList[T] = lst.grouped(len).flatMap(_.init).to(LazyList)
  def ludic: LazyList[Int] = 1 #:: LazyList.unfold(LazyList.from(2)){case n +: ns => Some((n, dropByN(ns, n)))}
  def triplets: LazyList[(Int, Int, Int)] = LazyList.from(1).map(n => (n, n + 2, n + 6)).filter{case (a, b, c) => Seq(a, b, c).forall(ludic.takeWhile(_ <= c).contains)}
}
Output:
First 25 Ludic Numbers: 1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107
Ludic Numbers <= 1000: 142
2000-2005th Ludic Numbers: 21475, 21481, 21487, 21493, 21503, 21511
Triplets <= 250: (1,3,7), (5,7,11), (11,13,17), (23,25,29), (41,43,47), (173,175,179), (221,223,227), (233,235,239)

Seed7

$ include "seed7_05.s7i";

const func set of integer: ludicNumbers (in integer: n) is func
  result
    var set of integer: ludicNumbers is {1};
  local
    var set of integer: sieve is EMPTY_SET;
    var integer: ludicNumber is 0;
    var integer: number is 0;
    var integer: count is 0;
  begin
    sieve := {2 .. n};
    while sieve <> EMPTY_SET do
      ludicNumber := min(sieve);
      incl(ludicNumbers, ludicNumber);
      count := 0;
      for number range sieve do
        if count rem ludicNumber = 0 then
          excl(sieve, number);
        end if;
        incr(count);
      end for;
    end while;
  end func;

const integer: limit is 22000;
const set of integer: ludicNumbers is ludicNumbers(limit);

const proc: main is func
  local
    var integer: number is 0;
    var integer: count is 0;
  begin
    write("First 25:");
    for number range ludicNumbers until count = 25 do
      write(" " <& number);
      incr(count);
    end for;
    writeln;
    count := 0;
    for number range ludicNumbers until number > 1000 do
      incr(count);
    end for;
    writeln("Ludics below 1000: " <& count);
    write("Ludic 2000 to 2005:");
    count := 0;
    for number range ludicNumbers until count >= 2005 do
      incr(count);
      if count >= 2000 then
        write(" " <& number);
      end if;
    end for;
    writeln;
    write("Triples below 250:");
    for number range ludicNumbers until number > 250 do
      if number + 2 in ludicNumbers and number + 6 in ludicNumbers then
        write(" (" <& number <& ", " <& number + 2 <& ", " <& number + 6 <& ")");
      end if;
    end for;
    writeln;
  end func;
Output:
First 25: 1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107
Ludics below 1000: 142
Ludic 2000 to 2005: 21475 21481 21487 21493 21503 21511
Triples below 250: (1, 3, 7) (5, 7, 11) (11, 13, 17) (23, 25, 29) (41, 43, 47) (173, 175, 179) (221, 223, 227) (233, 235, 239)

SequenceL

import <Utilities/Set.sl>;

ludic(v(1), result(1)) :=
	let
		n := head(v);
		filtered[i] := v[i] when (i-1) mod n /= 0;
	in 
	result when size(v) < 1 else
	ludic(filtered, result ++ [n]);
		
count : int(1) * int * int -> int;
count(v(1), top, index) :=
	index-1 when v[index] > top else
	count(v, top, index + 1);

main() :=
	let
		ludics := ludic(2...100000, [1]);
		ludics250 := ludics[1 ... count(ludics, 250, 1)];
		triplets[i] := [i, i+2, i+6] when elementOf(i+2, ludics250) and elementOf(i+6, ludics250)
							foreach i within ludics250;
	in
		"First 25:\n" ++ toString(ludics[1...25]) ++
		"\n\nLudics below 1000:\n" ++ toString(count(ludics, 1000, 1)) ++
		"\n\nLudic 2000 to 2005:\n" ++ toString(ludics[2000...2005]) ++
		"\n\nTriples below 250:\n" ++ toString(triplets) ;
Output:
First 25:
[1,2,3,5,7,11,13,17,23,25,29,37,41,43,47,53,61,67,71,77,83,89,91,97,107]

Ludics below 1000:
142

Ludic 2000 to 2005:
[21475,21481,21487,21493,21503,21511]

Triples below 250:
[[1,3,7],[5,7,11],[11,13,17],[23,25,29],[41,43,47],[173,175,179],[221,223,227],[233,235,239]]

Sidef

Translation of: Ruby
func ludics_upto(nmax=100000) {
  Enumerator({ |collect|
    collect(1)
    var arr = @(2..nmax)
    while (arr) {
      collect(var n = arr[0])
      arr.range.by(n).each {|i| arr[i] = nil}
      arr.compact!
    }
  })
}

func ludics_first(n) {
    ludics_upto(n * n.log2).first(n)
}

say("First 25 Ludic numbers: ",     ludics_first(25).join(' '))
say("Ludics below 1000: ",          ludics_upto(1000).len)
say("Ludic numbers 2000 to 2005: ", ludics_first(2005).last(6).join(' '))

var a = ludics_upto(250).to_a
say("Ludic triples below 250: ", a.grep{|x| a.contains_all([x+2, x+6]) } \
                                  .map {|x| '(' + [x, x+2, x+6].join(' ') + ')' } \
                                  .join(' '))
Output:
First 25 Ludic numbers: 1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107
Ludics below 1000: 142
Ludic numbers 2000 to 2005: 21475 21481 21487 21493 21503 21511
Ludic triples below 250: (1 3 7) (5 7 11) (11 13 17) (23 25 29) (41 43 47) (173 175 179) (221 223 227) (233 235 239)

Standard ML

open List;

fun Ludi [] = []
 |  Ludi (T as h::L) =
    let
     fun next (h:: L ) =
       let
        val nw  =  #2 (ListPair.unzip (filter (fn (a,b) => a mod #2 h <> 0) L) )
        in
        ListPair.zip ( List.tabulate(List.length nw,fn i=>i) ,nw)
        end
     in
      h :: Ludi ( next T)
 end;

val ludics = 1:: (#2 (ListPair.unzip(Ludi (ListPair.zip ( List.tabulate(25000,fn i=>i),tabulate (25000,fn i=>i+2)) )) ));

app ((fn e => print (e^" ")) o Int.toString ) (take (ludics,25));
length (filter (fn e=> e <= 1000) ludics);
drop (take (ludics,2005),1999);

output

1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107 val it = () : unit
- val it = 142 : int
- val it = [21475,21481,21487,21493,21503,21511] : int list

Tcl

Works with: Tcl version 8.6

The limit on the number of values generated is the depth of stack; this can be set to arbitrarily deep to go as far as you want. Provided you are prepared to wait for the values to be generated.

package require Tcl 8.6

proc ludic n {
    global ludicList ludicGenerator
    for {} {[llength $ludicList] <= $n} {lappend ludicList $i} {
	set i [$ludicGenerator]
	set ludicGenerator [coroutine L_$i apply {{gen k} {
	    yield [info coroutine]
	    while true {
		set val [$gen]
		if {[incr i] == $k} {set i 0} else {yield $val}
	    }
	}} $ludicGenerator $i]
    }
    return [lindex $ludicList $n]
}
# Bootstrap the generator sequence
set ludicList [list 1]
set ludicGenerator [coroutine L_1 apply {{} {
    set n 1
    yield [info coroutine]
    while true {yield [incr n]}
}}]

# Default of 1000 is not enough
interp recursionlimit {} 5000

for {set i 0;set l {}} {$i < 25} {incr i} {lappend l [ludic $i]}
puts "first25: [join $l ,]"

for {set i 0} {[ludic $i] <= 1000} {incr i} {}
puts "below=1000: $i"

for {set i 1999;set l {}} {$i < 2005} {incr i} {lappend l [ludic $i]}
puts "2000-2005: [join $l ,]"

for {set i 0} {[ludic $i] < 256} {incr i} {set isl([ludic $i]) $i}
for {set i 1;set l {}} {$i < 250} {incr i} {
    if {[info exists isl($i)] && [info exists isl([expr {$i+2}])] && [info exists isl([expr {$i+6}])]} {
	lappend l ($i,[expr {$i+2}],[expr {$i+6}])
    }
}
puts "triplets: [join $l ,]"
Output:
first25: 1,2,3,5,7,11,13,17,23,25,29,37,41,43,47,53,61,67,71,77,83,89,91,97,107
below=1000: 142
2000-2005: 21475,21481,21487,21493,21503,21511
triplets: (1,3,7),(5,7,11),(11,13,17),(23,25,29),(41,43,47),(173,175,179),(221,223,227),(233,235,239)

VBScript

Set list = CreateObject("System.Collections.Arraylist")
Set ludic = CreateObject("System.Collections.Arraylist")

'populate the list
For i = 1 To 25000
	list.Add i
Next

'set 1 as the first ludic number
ludic.Add list(0)
list.RemoveAt(0)

'variable to count ludic numbers <= 1000
up_to_1k = 1

'determine the succeeding ludic numbers
For j = 2 To 2005
	If list.Count > 0 Then
		If list(0) <= 1000 Then
			up_to_1k = up_to_1k + 1
		End If
		ludic.Add list(0)
	Else
		Exit For
	End If
	increment = list(0) - 1
	n = 0
	Do While n <= list.Count - 1
		list.RemoveAt(n)
		n = n + increment
	Loop
Next

'the first 25 ludics
WScript.StdOut.WriteLine "First 25 Ludic Numbers:"
For k = 0 To 24
	If k < 24 Then
		WScript.StdOut.Write ludic(k) & ", "
	Else
		WScript.StdOut.Write ludic(k)
	End If
Next
WScript.StdOut.WriteBlankLines(2)

'the number of ludics up to 1000
WScript.StdOut.WriteLine "Ludics up to 1000: "
WScript.StdOut.WriteLine up_to_1k
WScript.StdOut.WriteBlankLines(1)

'2000th - 2005th ludics
WScript.StdOut.WriteLine "The 2000th - 2005th Ludic Numbers:"
For k = 1999 To 2004
	If k < 2004 Then
		WScript.StdOut.Write ludic(k) & ", "
	Else
		WScript.StdOut.Write ludic(k)
	End If
Next
WScript.StdOut.WriteBlankLines(2)

'triplets up to 250: x, x+2, and x+6
WScript.StdOut.WriteLine "Ludic Triplets up to 250: "
triplets = ""
k = 0
Do While ludic(k) + 6 <= 250
	x2 = ludic(k) + 2
	x6 = ludic(k) + 6
	If ludic.IndexOf(x2,1) > 0 And ludic.IndexOf(x6,1) > 0 Then
		triplets = triplets & ludic(k) & ", " & x2 & ", " & x6 & vbCrLf
	End If
	k = k + 1
Loop
WScript.StdOut.WriteLine triplets
Output:
First 25 Ludic Numbers:
1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107

Ludics up to 1000: 
142

The 2000th - 2005th Ludic Numbers:
21475, 21481, 21487, 21493, 21503, 21511

Ludic Triplets up to 250: 
1, 3, 7
5, 7, 11
11, 13, 17
23, 25, 29
41, 43, 47
173, 175, 179
221, 223, 227
233, 235, 239

V (Vlang)

Translation of: Go
const max_i32 = 1<<31 - 1 // i.e. math.MaxInt32
// ludic returns a slice of ludic numbers stopping after
// either n entries or when max is exceeded.
// Either argument may be <=0 to disable that limit.
fn ludic(nn int, m int) []u32 {
    mut n := nn
    mut max := m
    if max > 0 && n < 0 {
        n = max_i32
    }
    if n < 1 {
        return []
    }
    if max < 0 {
        max = max_i32
    }
    mut sieve := []u32{len: 10760} // XXX big enough for 2005 ludics
    sieve[0] = 1
    sieve[1] = 2
    if n > 2 {
        // We start with even numbers already removed
        for i, j := 2, u32(3); i < sieve.len; i, j = i+1, j+2 {
            sieve[i] = j
        }
        // We leave the ludic numbers in place,
        // k is the index of the next ludic
        for k := 2; k < n; k++ {
            mut l := int(sieve[k])
            if l >= max {
                n = k
                break
            }
            mut i := l
            l--
            // last is the last valid index
            mut last := k + i - 1
            for j := k + i + 1; j < sieve.len; i, j = i+1, j+1 {
                last = k + i
                sieve[last] = sieve[j]
                if i%l == 0 {
                    j++
                }
            }
            // Truncate down to only the valid entries
            if last < sieve.len-1 {
                sieve = sieve[..last+1]
            }
        }
    }
    if n > sieve.len {
        panic("program error") // should never happen
    }
    return sieve[..n]
}
 
fn has(x []u32, v u32) bool {
    for i := 0; i < x.len && x[i] <= v; i++ {
        if x[i] == v {
            return true
        }
    }
    return false
}
 
fn main() {
    // ludic() is so quick we just call it repeatedly
    println("First 25: ${ludic(25, -1)}")
    println("Numner of ludics below 1000: ${ludic(-1, 1000).len}")
    println("ludic 2000 to 2005: ${ludic(2005, -1)[1999..]}")
 
    print("Tripples below 250:")
    x := ludic(-1, 250)
    for i, v in x[..x.len-2] {
        if has(x[i+1..], v+2) && has(x[i+2..], v+6) {
            print(", ($v ${v+2} ${v+6})")
        }
    }
    println('')
}
Output:
First 25: [1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107]
Numner of ludics below 1000: 142
ludic 2000 to 2005: [21475, 21481, 21487, 21493, 21503, 21511]
Tripples below 250:, (1 3 7), (5 7 11), (11 13 17), (23 25 29), (41 43 47), (173 175 179), (221 223 227), (233 235 239)

Wren

Translation of: Go
Library: Wren-fmt
import "./fmt" for Fmt

var ludic = Fn.new { |n, max|
    var maxInt32 = 2.pow(31) - 1
    if (max > 0 && n < 0) n = maxInt32
    if (n < 1) return []
    if (max < 0) max = maxInt32
    var sieve = List.filled(10760, 0)
    sieve[0] = 1
    sieve[1] = 2
    if (n > 2) {
        var j = 3
        for (i in 2...sieve.count) {
            sieve[i] = j
            j = j + 2
        }
        for (k in 2...n) {
            var l = sieve[k]
            if (l >= max) {
                n = k
                break
            }
            var i = l
            l = l - 1
            var last = k + i - 1
            var j = k + i + 1
            while (j < sieve.count) {
                last = k + i
                sieve[last] = sieve[j]
                if (i%l == 0) j = j + 1
                i = i + 1
                j = j + 1
            }
            if (last < sieve.count-1) sieve = sieve[0..last]
        }
    }
    if (n > sieve.count) Fiber.abort("Program error.")
    return sieve[0...n]
}

var has = Fn.new { |x, v|
    var i = 0
    while (i < x.count && x[i] <= v) {
        if (x[i] == v) return true
        i = i + 1
    }
    return false
}

System.print("First 25: %(ludic.call(25, -1))") 
System.print("Number of Ludics below 1000: %(ludic.call(-1, 1000).count)")
System.print("Ludics 2000 to 2005: %(ludic.call(2005, -1)[1999..-1])")
System.print("Triplets below 250:")
var x = ludic.call(-1, 250)
var i = 0
var triples = []
for (v in x.take(x.count-2)) {
    if (has.call(x[i+1..-1], v+2) && has.call(x[i+2..-1], v+6)) {
        triples.add([v, v+2, v+6])
    }
    i = i + 1
}
System.print(triples)
Output:
First 25: [1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107]
Number of Ludics below 1000: 142
Ludics 2000 to 2005: [21475, 21481, 21487, 21493, 21503, 21511]
Triplets below 250:
[[1, 3, 7], [5, 7, 11], [11, 13, 17], [23, 25, 29], [41, 43, 47], [173, 175, 179], [221, 223, 227], [233, 235, 239]]

XPL0

def  Size = 25000;
char Sieve(1+Size);
int  I, Count, Ludic;
[\Make sieve for Ludic numbers
for I:= 1 to Size do Sieve(I):= true;
Ludic:= 2;
loop    [I:= Ludic;  Count:= Ludic;
        loop    [repeat I:= I+1;
                    if I > Size then quit;
                until   Sieve(I);
                Count:= Count-1;
                if Count = 0 then
                    [Sieve(I):= false;
                    Count:= Ludic;
                    ];
                ];
        repeat  Ludic:= Ludic+1;
                if Ludic > Size then quit;
        until   Sieve(Ludic);
        ];
\Show first 25 Ludic numbers
Count:= 0;  I:= 1;
loop    [if Sieve(I) then
            [IntOut(0, I);  ChOut(0, ^ );
            Count:= Count+1;
            if Count >= 25 then quit;
            ];
        I:= I+1;
        ];
CrLf(0);
\Show how many Ludic numbers are <= 1000
Count:= 0;
for I:= 1 to 1000 do
    if Sieve(I) then Count:= Count+1;
IntOut(0, Count);
CrLf(0);
\Show Ludic numbers from 2000 to 2005
Count:= 0;  I:= 1;
loop    [if Sieve(I) then
            [Count:= Count+1;
            if Count >= 2000 then
                [IntOut(0, I);  ChOut(0, ^ )];
            if Count >= 2005 then quit;
            ];
        I:= I+1;
        ];
CrLf(0);
\Show triplets of Ludic numbers < 250
for I:= 1 to 250-1-6 do
    if Sieve(I) & Sieve(I+2) & Sieve(I+6) then
        [ChOut(0, ^();
        IntOut(0, I);  ChOut(0, ^ );
        IntOut(0, I+2);  ChOut(0, ^ );
        IntOut(0, I+6);  Text(0, ") ");
        ];
CrLf(0);
]
Output:
1 2 3 5 7 11 13 17 23 25 29 37 41 43 47 53 61 67 71 77 83 89 91 97 107 
142
21475 21481 21487 21493 21503 21511 
(1 3 7) (5 7 11) (11 13 17) (23 25 29) (41 43 47) (173 175 179) (221 223 227) (233 235 239) 

zkl

This solution builds an iterator with filters, one for each Ludic number, each extending the previous filter. A "master" iterator sits at the top and provides the interface. When the next Ludic number is requested, the next odd number sent down the list of filters and if it makes to the end, it is the next Ludic number. A new filter is then attached [to the iterator] with a starting index of 1 and which indexes to strike.

fcn dropNth(n,seq){
   seq.tweak(fcn(n,skipper,idx){ if(0==idx.inc()%skipper) Void.Skip else n }
	     .fp1(n,Ref(1)))  // skip every nth number of previous sequence
} 
fcn ludic{  //-->Walker
   Walker(fcn(rw){ w:=rw.value; n:=w.next(); rw.set(dropNth(n,w)); n }
	  .fp(Ref([3..*,2])))  // odd numbers starting at 3
   .push(1,2);  // first two Ludic numbers
}
ludic().walk(25).toString(*).println();
ludic().reduce(fcn(sum,n){ if(n<1000) return(sum+1); return(Void.Stop,sum); },0).println();
ludic().drop(1999).walk(6).println();  // Ludic's between 2000 & 2005

ls:=ludic().filter(fcn(n){ (n<250) and True or Void.Stop  });  // Ludic's < 250
ls.filter('wrap(n){ ls.holds(n+2) and ls.holds(n+6) }).apply(fcn(n){ T(n,n+2,n+6) }).println();
Output:
L(1,2,3,5,7,11,13,17,23,25,29,37,41,43,47,53,61,67,71,77,83,89,91,97,107)
142
L(21475,21481,21487,21493,21503,21511)
L(L(1,3,7),L(5,7,11),L(11,13,17),L(23,25,29),L(41,43,47),L(173,175,179),L(221,223,227),L(233,235,239))