Ludic numbers

From Rosetta Code
Revision as of 22:30, 10 July 2016 by rosettacode>Purple24 (→‎{{header|Elixir}}: used Enum.drop_every)
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.
  • A triplet is any three numbers             where all three numbers are also ludic numbers.



Stretch goal

Show all triplets of ludic numbers < 250.

360 Assembly

Translation of: Fortran

<lang 360asm>* 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</lang>
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 <lang ABAP>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.</lang>

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 

ALGOL 68

<lang algol68># find some Ludic numbers #

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

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

  1. 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</lang>

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

AutoHotkey

Works with: AutoHotkey 1.1

<lang AutoHotkey>#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 }</lang>

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

<lang c>#include <stdio.h>

  1. 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; }</lang>

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

<lang cpp>

  1. include <vector>
  2. 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" );

} </lang>

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

<lang 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)))))</lang>
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))

D

opApply Version

Translation of: Python
Translation of: Perl 6

<lang d>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);

}</lang>

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. <lang d>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);

}</lang> 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

<lang d>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);

}</lang> The result is the same.

Eiffel

<lang 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 </lang> Test: <lang Eiffel> 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 </lang>

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

<lang elixir>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</lang>

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

Fortran

Works with: Fortran version 95 and later

<lang fortran>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</lang> 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]

Go

<lang 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() }</lang> 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

<lang haskell>import Data.List (unfoldr, genericSplitAt)

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

 dropEvery n = concat . map 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</lang>
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. <lang haskell>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</lang>

Icon and Unicon

This is inefficient, but was fun to code as a cascade of filters. Works in both languages. <lang unicon>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</lang>

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):<lang j> ludic =: _1 |.!.1 [: {."1 [: (#~ 0 ~: {. | i.@#)^:a: 2 + i.</lang> Examples:<lang j> # 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</lang>

Java

Works with: Java version 1.5+

This example uses pre-calculated ranges for the first and third task items (noted in comments). <lang java5>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))); } }</lang>

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

Julia

<lang 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 </lang>

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

Lua

<lang 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)</lang>

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

<lang Mathematica>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];</lang>

Output:
Ludic[[;; 25]]
LengthWhile[Ludic, # < 1000 &]
Ludic[[2000 ;; 2005]]
Select[Subsets[Select[Ludic, # < 250 &], {3}], Differences[#] == {2, 4} &]

{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}}

Oforth

<lang 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
     ] ;</lang>
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.

<lang parigp> \\ 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,") "))); } </lang>

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.

<lang parigp> \\ 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,") ")))); } </lang>

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 perl 6 . Runtime nearly quadratic: maxLudicCnt = 10000 -> 0.03 s =>maxLudicCnt= 100000 -> 3 s <lang pascal>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. { 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}</lang>

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

Perl

The "ludic" subroutine caches the longest generated sequence so far. It also generates the candidates only if no candidates remain. <lang perl>#!/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;</lang>
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)

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... :-) <lang perl6>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 $b ∈ l250 and $c ∈ l250;
   }</lang>
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>)

PicoLisp

<lang 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)</lang>

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

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

<lang plsql>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..2005th 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; / </lang>

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

<lang PowerShell> function Get-Ludic {

   [OutputType([PSObject])]
   Param
   (
       # Lower limit 13 (takes that many to make a triplet,) upper limit 1,000,000.
       [Parameter(Mandatory=$false, Position=0)]
       [ValidateRange(13,1000000)]
       [int]
       $Limit = 25000
   )
   # The 'cheaters' method of creating a blank PSObject
   [PSObject]$ludic = "LUDICrous" | Select-Object -Property Numbers, Triplets
   # Set 1 as the first element in the ludic number list.
   [System.Collections.ArrayList]$ludicNumbers = @(1)
   # Create a list of all remaining numbers within limit.
   [System.Collections.ArrayList]$numbers = 2..$Limit
   # Find the Ludic numbers.
   for ($j = 2; $j -lt $Limit; $j++)
   { 
       if ($numbers.Count)
       {
           $ludicNumbers.Add($numbers[0]) | Out-Null
       }
       else
       {
           break
       }
       $i = $numbers[0] - 1
       $n = 0
       while ($n -le $numbers.Count - 1)
       {
           $numbers.RemoveAt($n)
           $n += $i
       }
   }
   # Add the Ludic number array to the object.
   $ludic.Numbers  = $ludicNumbers
   # Find the Ludic number triplets.
   $2dArray = 'Set-Variable -Name ludicTriplets -Value '
   $k = 0
   while ($ludicNumbers[$k] + 6 -le $ludicNumbers.Count)
   {
       $nPlus2 = $ludicNumbers[$k] + 2
       $nPlus6 = $ludicNumbers[$k] + 6
       if ($ludicNumbers.IndexOf($nPlus2, 1) -gt 0 -and
           $ludicNumbers.IndexOf($nPlus6, 1) -gt 0)
       {
           Set-Variable -Name "array$k" -Value @($ludicNumbers[$k],$nPlus2,$nPlus6)
           $2dArray += "`$array$k,"
       }
       $k += 1
   }
   Invoke-Expression ($2dArray.TrimEnd(","))
   # Add the Ludic triplet array to the object.
   $ludic.Triplets = $ludicTriplets
   return $ludic

} </lang> The variable $ludic contains an object with all Ludic numbers and triplets within limit range: <lang PowerShell> $ludic = Get-Ludic -Limit 25000

$ludic </lang>

Output:

Numbers                                                                                    Triplets                                                                                 
-------                                                                                    --------                                                                                 
{1, 2, 3, 5...}                                                                            {1 3 7, 5 7 11, 11 13 17, 23 25 29...}                                                   

<lang PowerShell> Write-Host "First 25 Ludic numbers  : $($ludic.Numbers[0..24] -join ', ')" Write-Host "Total Ludic numbers <= 1000 : $(($ludic.Numbers | Where-Object {$_ -le 1000}).Count)" Write-Host "Ludic numbers 2000 to 2005  : $($ludic.Numbers[2000..2005] -join ', ')" Write-Host "Ludic triplets below 250  :" -NoNewline; for ($i = 0; $i -lt $ludic.Triplets.Count; $i++)

                                                       {
                                                           if ($ludic.Triplets[$i][2] -lt 250) { $n = $i }
                                                       }
                                                       $ludic.Triplets[0..$n] |
                                                           Format-Wide {$_.ToString().PadLeft(3)} -Column 3 -Force

</lang>

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
Total Ludic numbers <= 1000 : 142
Ludic numbers 2000 to 2005  : 21481, 21487, 21493, 21503, 21511, 21523
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

<lang python>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))</lang>
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. <lang python>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]</lang>

Output is the same as for the fast version.

Racket

<lang 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))))</lang>
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

REXX

<lang rexx>/*REXX program displays (a range of) ludic numbers, or a count of 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=250-1 /* " " " " " " */ say 'The first ' N " ludic numbers: " ludic(n) /*display title for what's coming next.*/ say say "There are " words(ludic(-count)) ' ludic numbers from 1───►'count " (inclusive)." say say "The " bot ' to ' top " ludic numbers are: " ludic(bot,top) $=ludic(-triples) 0 0; #=0; @= say

    do j=1  for words($);          _=word($,j)  /*it is known that ludic   _   exists. */
    if wordpos(_+2, $)==0  |  wordpos(_+6, $)==0  then iterate  /*Not triple?  Skip it.*/
    #=#+1;    @=@ '◄'_  _+2  _+6"► "            /*bump the triple counter,  and  ···   */
    end   /*j*/                                 /* [↑]  append the found triple ──►  @ */

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,h; am=abs(m); if h\== then am=h; $=1 2; yes=m>0 | h\== @= /*$≡ludic numbers superset; @≡sequence*/

           do j=3  by 2  to  am*max(1, 15*yes)  /*construct an initial list of numbers.*/
           @=@ j                                /* [↓]  construct a  ludic  sequence.  */
           end   /*j*/                          /* [↑]  high limit:  approx or exact.  */

@=@' ' /*append a blank to the number sequence*/

           do  while words(@)\==0; f=word(@,1)  /* [↓]  examine the first word.        */
           $=$ f                                /*append this first word to the list.  */
                do d=1  by f  while d<=words(@) /*use 1st number, elide all occurrences*/
                y=word(@,d)                     /*obtain the  Yth  word  of  @  string.*/
                @=changestr(' 'y" ", @, ' . ')  /*delete the number in the sequence.   */
                end   /*d*/                     /* [↑]  done eliding the "1st" number. */
           @=translate(@, , .)                  /*translate periods (dots)  to blanks. */
           end        /*while*/                 /* [↑]  done eliding ludic numbers.    */

if h== then return subword($, 1, am) /*return a range of ludic numbers. */

              return subword($, am, h-m+1)      /*return a section of a range.         */</lang>

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 from 1───►1000  (inclusive).

The  2000  to  2005  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►

Ruby

<lang 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</lang>
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]]

Seed7

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

<lang 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(' '))</lang>
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)

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. <lang tcl>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]

}

  1. 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]}

}}]

  1. 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 ,]"</lang>

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

<lang vb> 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 </lang>

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

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. <lang zkl>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

}</lang> <lang zkl>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();</lang>

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