Ludic numbers: Difference between revisions
Redherring (talk | contribs) |
m →{{header|REXX}}: added/changed comments and whitespace. |
||
Line 3,319:
=={{header|REXX}}==
<lang rexx>/*REXX program
parse arg N count bot top triples . /*obtain optional arguments from the CL*/
if N=='' | N=="," then N=
if count=='' | count=="," then count=
if bot=='' | bot=="," then bot=
if top=='' | top=="," then top=
if triples=='' | triples=="," then triples=
say 'The first ' N " ludic numbers:
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).*/
_= word($, j) /*it is known that ludic _ exists. */
if _>=triples then leave /*only process up to a specific number.*/
if wordpos(_+2, $)==0
#= # + 1
end /*j*/
say
if @=='' then say 'From 1──►'triples", no triples found."
Line 3,344 ⟶ 3,348:
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
ludic: procedure; parse arg m,,@; $= 1 2
end /*j*/
@= @' ';
do while n\==0;
$= $ f
do d=1 by
@=
@= translate(@, , .) /*change dots to blanks; count numbers.*/
end /*while*/ /* [↑] done eliding ludic numbers. */
return subword($, 1, m) /*return a range of ludic numbers. */</lang>
Some older REXXes don't have a '''changestr''' BIF, so one is included here ──► [[CHANGESTR.REX]].
|
Revision as of 16:25, 24 May 2020
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).
234567891011121314151617181920212223242526...
- (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).
35 7911 131517 192123 252729 313335 373941 434547 4951...
- 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).
57 11 13 171923 25 29 313537 41 43 474953 55 59 616567 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).
711 13 17 23 25 293137 41 43 47 53 555961 67 71 73 77 838589 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.
360 Assembly
<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
Ada
<lang 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;</lang>
- 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
<lang algol68># 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</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
<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>
- 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 csharp>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; }
}</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 = 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++
<lang cpp>
- 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" );
} </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))
Common Lisp
<lang 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))))</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 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
<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
<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]]
Factor
<lang 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</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 } Count of ludic numbers less than 1000: 142 Ludic numbers 2000 to 2005: { 21475 21481 21487 21493 21503 21511 }
Fortran
<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]
FreeBASIC
<lang 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 </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 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
<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 = 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</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
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]]
JavaScript
ES6
<lang JavaScript>/**
* 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(', ')); }
});</lang>
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
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
Kotlin
<lang scala>// 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 } }
}</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 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
<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}}
Objeck
<lang objeck>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()); }; }
} </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]
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
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 Raku. 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.</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 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. <lang pascal>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.</lang>
- 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. <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)
Phix
<lang Phix>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)})</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} 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}}
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>
- 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() </lang> <lang PowerShell>
- 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 ", " } </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
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.
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.
<lang python>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}]')
</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] 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]
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
Raku
(formerly Perl 6)
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>)
REXX
<lang 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. */</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 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
<lang 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
</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] Ludic numbers below 1000: 142 the 2000..2005th ludic numbers are: [21475, 21481, 21487, 21493, 21503, 21511]
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]]
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.
<lang scala>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)}
}</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 <= 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
<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)
SequenceL
<lang 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) ; </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
<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
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]
}
- 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 ,]"</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))
- Programming Tasks
- Sieves
- 360 Assembly
- ABAP
- Ada
- ALGOL 68
- AutoHotkey
- C
- C sharp
- C++
- Clojure
- Common Lisp
- D
- Eiffel
- Elixir
- Factor
- Fortran
- FreeBASIC
- Go
- Haskell
- Icon
- Unicon
- J
- Java
- JavaScript
- Julia
- Kotlin
- Lua
- Mathematica
- Objeck
- Oforth
- PARI/GP
- Pascal
- Perl
- Phix
- PicoLisp
- PL/I
- PL/SQL
- PowerShell
- Python
- Racket
- Raku
- REXX
- Ring
- Ruby
- Scala
- Seed7
- SequenceL
- Sidef
- Tcl
- VBScript
- Zkl