ClearAll[GetLuckies, GetEvenLuckies]
GetLuckies[max_] := Module[{luckies, f, i},
  luckies = Range[1, max, 2];
  f[n_] := Block[{k = luckies[[n]]}, luckies = Delete[luckies, Table[{k}, {k, k, [email protected], k}]]];
  i = 2;
  While[i < Length[luckies],
   f[i];
   i++
   ];
  luckies
  ]
GetEvenLuckies[max_] := Module[{lst, i, len},
  lst = Range[2, max, 2];
  i = 2;
  While[i <= (len = [email protected]) && (k = lst[[i]]) <= len,
   lst = Drop[lst, {k, len, k}];
   i++
   ];
  lst
  ]
GiveLucky[s_String] := GiveLucky[StringSplit[s, " "]]
GiveLucky[args_List] := Module[{argc = Length[args], j, k, type},
  If[argc > 3,
   Print["Too many arguments"]
   ,
   If[argc == 0,
    Print["Too few arguments"]
    ,
    Switch[argc, 1,
     j = Interpreter["Integer"][args[[1]]];
     If[! FailureQ[j],
      If[j > 0,
       [email protected][20 j][[j]]
       ,
       Print["j should be positive"]
       ]
      ,
      Print["one argument that is not an integer"]
      ]
     , 2,
     j = Interpreter["Integer"][args[[1]]];
     k = Interpreter["Integer"][args[[2]]];
     If[! FailureQ[j] \[And] ! FailureQ[k],
      If[j > 0,
       If[k > 0,
        [email protected][20 k][[j ;; k]]
        ,
        [email protected][GetLuckies[-k], GreaterEqualThan[j]]
        ]
       ,
       Print["j should be positive"]
       ]
      ,
      Print["one of the two arguments is not an integer\[Ellipsis]"]
      ]
     , 3,
     If[args[[2]] === ",",
      j = Interpreter["Integer"][args[[1]]];
      If[! FailureQ[j],
       If[j > 0,
        type = args[[3]];
        If[MatchQ[type, "evenLucky" | "lucky"],
         If[type === "evenLucky",
          [email protected][20 j][[j]]
          ,
          [email protected][20 j][[j]]
          ]
         ,
         Print["unknown type ", type]
         ]
        ,
        Print["j should be positive"]
        ]
       ,
       Print["j should be an integer"]
       ]
      ,
      j = Interpreter["Integer"][args[[1]]];
      k = Interpreter["Integer"][args[[2]]];
      If[! FailureQ[j] \[And] ! FailureQ[k],
       If[j > 0,
        type = args[[3]];
        If[k > 0,
         If[MatchQ[type, "evenLucky" | "lucky"],
          If[type === "evenLucky",
           [email protected][20 k][[j ;; k]]
           ,
           [email protected][20 k][[j ;; k]]
           ]
          ,
          Print["unknown type ", type]
          ]
         ,
         If[MatchQ[type, "evenLucky" | "lucky"],
          If[type === "evenLucky",
           [email protected][GetEvenLuckies[-k], GreaterEqualThan[j]]
           ,
           [email protected][GetLuckies[-k], GreaterEqualThan[j]]
           ]
          ,
          Print["unknown type ", type]
          ]
         ]
        ,
        Print["j should be positive"]
        ]
       ,
       Print["one of the two arguments is not an integer\[Ellipsis]"]
       ]
      ]
     ]
    ]
   ]
  ]
GiveLucky[[email protected]$ScriptCommandLine]


import os, strformat, strutils

type LuckyKind {.pure.} = enum Lucky = "lucky", EvenLucky = "evenlucky"

const NoValue = 0   # Indicates that no value have been specified.

####################################################################################################
# Lucky numbers generation.

func initLuckyNumbers(nelems: int; kind: LuckyKind): seq[int] =
  ## Initialize a list of lucky numbers.
  result = newSeqOfCap[int](nelems)
  for i in 0..<nelems:
    var k = i
    for j in countdown(result.high, 1):
      k = k * result[j] div (result[j] - 1)
    result.add 2 * k + 1 + ord(kind)

####################################################################################################
# Printing.

template name(kind: LuckyKind): string =
  if kind == Lucky: "Lucky" else: "Even lucky"

proc printSingle(j: int; kind: LuckyKind) =
  ## Print the lucky number at a given index.
  let luckySeq = initLuckyNumbers(j, kind)
  echo &"{name(kind)} number at index {j} is {luckySeq[j - 1]}"

proc printRange(j, k: int; kind: LuckyKind) =
  ## print the luck numbers in a range of indexes.
  let luckySeq = initLuckyNumbers(k, kind)
  var list = &"{name(kind)} numbers at indexes {j} to {k} are: "
  let start = list.len
  for idx in (j - 1)..(k - 1):
    list.addSep(", ", start)
    list.add $luckySeq[idx]
  echo list

proc printInRange(j, k: int; kind: LuckyKind) =
  ## Print the lucky numbers in a range of values.
  let luckySeq = initLuckyNumbers(k, kind)  # "k" is greater than needed.
  var list = &"{name(kind)} numbers between {j} to {k} are: "
  let start = list.len
  for val in luckySeq:
    if val > k: break
    if val > j:
      list.addSep(", ", start)
      list.add $val
  echo list

####################################################################################################
# Command line parsing.

proc parseCommandLine(): tuple[j, k: int; kind: LuckyKind] =
  ## Parse the command line.

  # Internal exception to catch invalid argument value.
  type InvalidArgumentError = object of ValueError

  template raiseError(message, value = "") =
    ## Raise an InvalidArgumentError.
    raise newException(InvalidArgumentError, message & value & '.')

  result = (Novalue, Novalue, Lucky)

  try:

    if paramCount() notin 1..3: raiseError "Wrong number of arguments"

    # First argument: "j" value.
    let p1 = paramStr(1)
    try:
      result.j = parseInt(p1)
      if result.j <= 0: raiseError "Expected a positive number, got: ", p1
    except ValueError:
      raiseError "Expected an integer, got: ", p1

    # Second argument: "k" value or a comma.
    if paramCount() > 1:
      let p2 = paramStr(2)
      if p2 == ",":
        # Must be followed by the kind of lucky number.
        if paramCount() != 3: raiseError "Missing kind argument"
      else:
        try:
          result.k = parseInt(p2)
          if result.k == 0: raiseError "Expected a non null number, got: ", p2
        except ValueError:
          raiseError "Expected an integer, got: ", p2

    # Third argument: number kind.
    if paramCount() == 3:
      let p3 = paramStr(3)
      try:
        result.kind = parseEnum[LuckyKind](p3.toLowerAscii())
      except ValueError:
        raiseError "Wrong kind: ", p3

  except InvalidArgumentError:
    quit getCurrentExceptionMsg()

#———————————————————————————————————————————————————————————————————————————————————————————————————
# Main program.

let (j, k, kind) = parseCommandLine()

if k == NoValue:
  # Print jth value.
  printSingle(j, kind)

elif k > 0:
  # Print jth to kth values.
  printRange(j, k, kind)

else:
  # Print values in range j..(-k).
  printInRange(j, -k, kind)


use Perl6::GatherTake;

sub luck {
my($a,$b) = @_;

gather {
    my $i = $b;
    my(@taken,@rotor,$j);

    take 0; # 0th index is a placeholder
    push @taken, take $a;

    while () {
        for ($j = 0; $j < @rotor; $j++) {
            --$rotor[$j] or last;
        }
        if ($j < @rotor) {
            $rotor[$j] = $taken[$j+1];
        }
        else {
            take $i;
            push @taken, $i;
            push @rotor, $i - @taken;
        }
        $i += 2;
    }
}
}

# fiddle with user input
$j = shift || usage();
$k = shift || ',';
$l = shift || 'lucky';
usage() unless $k =~ /,|-?\d+/;
usage() unless $l =~ /^(even)?lucky$/i;
sub usage { print "Args must be:  j [,|k|-k] [lucky|evenlucky]\n" and exit }

# seed the iterator
my $lucky = $l =~ /^l/i ? luck(1,3) : luck(2,4);

# access values from 'lazy' list
if ($k eq ',') {
    print $lucky->[$j]
} elsif ($k > $j) {
    print $lucky->[$_] . ' ' for $j..$k
} elsif ($k < 0) {
    while () { last if abs($k) < $lucky->[$i++] } # must first extend the array
    print join ' ', grep { $_ >= $j and $_ <= abs($k) } @$lucky
}

print "\n"


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


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


: test-seq  ( start stop inc -- )
  cr rot dup ." start: " 2 .r
  rot dup ."  stop: " 2 .r
  rot dup ."  inc: " 2 .r ."  | "
  -rot swap do i . dup +loop drop ;
-2  2  1 test-seq
-2  2  0 test-seq
-2  2 -1 test-seq
-2  2 10 test-seq
 2 -2  1 test-seq
 2  2  1 test-seq
 2  2 -1 test-seq
 2  2  0 test-seq
 0  0  0 test-seq


data -2,2,1,"Normal",-2,2,0,"Zero increment",-2,2,-1,"Increments away from stop value"
data -2,2,10,"First increment is beyond stop value",2,-2,1,"Start more than stop: positive increment"
data 2,2,1,"Start equal stop: positive increment",2,2,-1,"Start equal stop: negative increment"
data 2,2,0,"Start equal stop: zero increment",0,0,0,"Start equal stop equal zero: zero increment"

dim as integer i, start, fin, inc, vr, count
dim as string cmt
for i = 1 to 9
    count = 0
    read start, fin, inc, cmt
    print cmt
    print using "  Looping from ### to ### in increments of ##"; start; fin; inc
    for vr = start to fin step inc
        print "        Loop index = ",vr
        count += 1
        if count = 10 then
            print "        Breaking infinite loop"
            exit for
        end if
    next vr
    print "  Loop finished"
    print
    print
next i


package main

import "fmt"

type S struct {
    start, stop, incr int
    comment          string
}

var examples = []S{
    {-2, 2, 1, "Normal"},
    {-2, 2, 0, "Zero increment"},
    {-2, 2, -1, "Increments away from stop value"},
    {-2, 2, 10, "First increment is beyond stop value"},
    {2, -2, 1, "Start more than stop: positive increment"},
    {2, 2, 1, "Start equal stop: positive increment"},
    {2, 2, -1, "Start equal stop: negative increment"},
    {2, 2, 0, "Start equal stop: zero increment"},
    {0, 0, 0, "Start equal stop equal zero: zero increment"},
}

func sequence(s S, limit int) []int {
    var seq []int
    for i, c := s.start, 0; i <= s.stop && c < limit; i, c = i+s.incr, c+1 {
        seq = append(seq, i)
    }
    return seq
}

func main() {
    const limit = 10
    for _, ex := range examples {
        fmt.Println(ex.comment)
        fmt.Printf("Range(%d, %d, %d) -> ", ex.start, ex.stop, ex.incr)
        fmt.Println(sequence(ex, limit))
        fmt.Println()
    }
}


with javascript_semantics
constant luckyMax = 120000

sequence lucky

procedure filterLucky()
    integer n = 2
    while n<=length(lucky) do
        integer m = lucky[n],
                l = m-1
        for k=m+1 to length(lucky) do
            if mod(k,m)!=0 then
                l += 1
                lucky[l] = lucky[k]
            end if
        end for
        if l>=length(lucky) then exit end if
        lucky = lucky[1..l]
        n += 1
    end while
end procedure

constant helptxt = """
   argument(s)   |  what is displayed
=======================================
 j               |  jth lucky number
 j [,] lucky     |  jth lucky number
 j [,] evenLucky |  jth even lucky number
 j k             |  jth through kth (inclusive) lucky numbers
 j k lucky       |  jth through kth (inclusive) lucky numbers
 j k evenLucky   |  jth through kth (inclusive) even lucky numbers
 j -k            |  all lucky numbers in the range j to k
 j -k lucky      |  all lucky numbers in the range j to k
 j -k evenLucky  |  all even lucky numbers in the range j to k
"""

procedure fatal(string msg)
    puts(1,msg)
    puts(1,helptxt)
    {} = wait_key()
    abort(0)
end procedure

procedure process(sequence cl)
    --
    -- Allow eg "lucky j , evenLucky" to be == "lucky j evenLucky"
    --
    if length(cl)=3 and cl[2]="," then cl[2..2] = {} end if
    integer j, k
    bool single = true, range = true, oddluck = true
    for i=1 to length(cl) do
        string cli = cl[i]
        if cli[1]<='9' then     -- (includes '-')
            sequence d = scanf(cl[i],"%d")
            if length(d)!=1 then
                fatal("unrecognised "&cli)
            end if
            if i>2 then
                fatal("too many numbers")
            end if
            integer n = d[1][1]
            if i=1 then
                if n<1 then
                    fatal("first argument must be a positive integer")
                end if
                j = n
            else
                single = false
                if n<0 then
                    range = false
                    n = -n
                end if
                if n<j then
                    fatal("second argument cannot be less than first")
                end if
                k = n
            end if
        else
            integer l = find(cli,{"lucky","evenLucky"})
            if l=0 then
                fatal("unrecognised "&cli)
            end if
            if i!=length(cl) then
                fatal(cli&" must be last parameter")
            end if
            oddluck = (l=1)
        end if
    end for

    lucky = tagset(luckyMax,2-oddluck,2)
    filterLucky()
    printf(1,"Output when args are %s\n",{join(cl)})
    string evenstr = iff(oddluck?"":"even ")
    if single then
        if j>length(lucky) then
            fatal(sprintf("the argument, %d, is too big", j))
        end if
        printf(1,"Lucky %snumber %d = %d\n",{evenstr,j, lucky[j]})
    elsif range then
        if k>length(lucky) then
            fatal(sprintf("the argument, %d, is too big", k))
        end if
        printf(1,"Lucky %snumbers %d to %d are: %v\n",{evenstr,j,k,lucky[j..k]})
    else
        if j>lucky[$] then
            fatal("start of range is too big")
        elsif k>lucky[$] then
            fatal("end of range is too big")
        end if
        integer m = abs(binary_search(j,lucky)),
                n = binary_search(k,lucky)
        if n<0 then n = -n-1 end if
        printf(1,"Lucky %snumbers between %d and %d are: %v\n", {evenstr,j,k,lucky[m..n]})
    end if
end procedure

procedure main()
    sequence cl = command_line()
    if length(cl)=2 then
--      fatal("at least one argument must be supplied") -- (if preferred)
        sequence tests = {"1 20",
                          "1 20 evenLucky",
                          "20 lucky",
                          "20 evenLucky",
                          "6000 -6100",
                          "6000 -6100 evenLucky",
                          "10000 lucky",
                          "10000 evenLucky"}
        -- (done this way to exercise the real command line handling...)
        if cl[1]=cl[2] then                     -- (compiled)
            cl = cl[1..1]
        elsif platform()=WINDOWS then           -- (and interpreted)
            cl[1] = substitute(cl[1],"pw","p")  -- (pw.exe -> p.exe)
        end if
        for i=1 to length(cl) do
            if find(' ',cl[i]) then cl[i] = sprintf("\"%s\"",{cl[i]}) end if
        end for
        for t=1 to length(tests) do
            if platform()=JS then
                -- (...except when we can't do that, of course)
                process(split(tests[t]))
            else
                string cmd = join(append(deep_copy(cl),tests[t]))
--              printf(1,"running %s\n",{cmd})
                {} = system_exec(cmd)
            end if
        end for
        puts(1, "tests complete\n")
        {} = wait_key()
    else
        cl = cl[3..$] -- ({1,2} are {interperter,source} or {exe,exe})
        process(cl)
    end if
end procedure
main()


/*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. */


import Data.List

main = putStrLn $ showTable True '|' '-' '+' table

table = [["start","stop","increment","Comment","Code","Result/Analysis"]
        ,["-2","2","1","Normal","[-2,-1..2] or [-2..2]",show [-2,-1..2]]
        ,["-2","2","0","Zero increment","[-2,-2..2]","Infinite loop of -2 <=> repeat -2"]
        ,["-2","2","-1","Increments away from stop value","[-2,-3..2]",show [-2,-3..2]]
        ,["-2","2","10","First increment is beyond stop value","[-2,8..2]",show [-2,8..2]]
        ,["2","-2","1","Start more than stop: positive increment","[2,3.. -2]",show [2,3.. -2]]
        ,["2","2","1","Start equal stop: positive increment","[2,3..2]",show [2,3..2]]
        ,["2","2","-1","Start equal stop: negative increment","[2,1..2]",show [2,1..2]]
        ,["2","2","0","Start equal stop: zero increment","[2,2..2]","Infinite loop of 2 <=> repeat 2"]
        ,["0","0","0","Start equal stop equal zero: zero increment","[0,0..0]", "Infinite loop of 0 <=> repeat 0"]]

showTable::Bool -> Char -> Char -> Char -> [[String]] -> String
showTable _ _ _ _ [] = []
showTable header ver hor sep contents = unlines $ hr:(if header then z:hr:zs else intersperse hr zss) ++ [hr]
   where
   vss = map (map length) $ contents
   ms = map maximum $ transpose vss ::[Int]
   hr = concatMap (\ n -> sep : replicate n hor) ms ++ [sep]
   top = replicate (length hr) hor
   bss = map (\ps -> map (flip replicate ' ') $ zipWith (-) ms ps) $ vss
   zss@(z:zs) = zipWith (\us bs -> (concat $ zipWith (\x y -> (ver:x) ++ y) us bs) ++ [ver]) contents bss


(off *Even)

(de nn (Lst N)
   (seek
      '((L)
         (when (car L) (=0 (dec 'N))) )
      Lst ) )

(de lucky (B)
   (let Lst (range (if *Even 2 1) B 2)
      (for A (cdr Lst)
         (for (L (nn Lst A) L (nn (cdr L) A))
            (set L) ) )
      (filter bool Lst) ) )

(argv . *Argv) # without validations
(when (= "evenLucky" (last *Argv)) (on *Even))
(setq *Lst (lucky 7000))
(let (A (format (car *Argv))  B (format (cadr *Argv)))
   (println
      (if (lt0 B)
         (filter '((N) (<= A N (abs B))) *Lst)
         (head B (nth *Lst A)) ) ) )


from __future__ import print_function

def lgen(even=False, nmax=1000000):
    start = 2 if even else 1
    n, lst = 1, list(range(start, nmax + 1, 2))
    lenlst = len(lst)
    yield lst[0]
    while n < lenlst and lst[n] < lenlst:
        yield lst[n]
        n, lst = n + 1, [j for i,j in enumerate(lst, 1) if i % lst[n]]
        lenlst = len(lst)
    # drain
    for i in lst[n:]:
        yield i


F isPrime(p)
   I p < 2 | p % 2 == 0
      R p == 2
   L(i) 3..Int(sqrt(p))
      I p % i == 0
         R 0B
   R 1B

F isMersennePrime(p)
   I !isPrime(p)
      R 0B
   I p == 2
      R 1B
   V mp = BigInt(2) ^ p - 1
   V s = BigInt(4)
   L 3..p
      s = (s ^ 2 - 2) % mp
   R s == 0

L(p) 2..2299
   I isMersennePrime(p)
      print(‘M’p, end' ‘ ’)


# 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


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


import Algorithms as algo;

class Example {
  _start = none;
  _stop = none;
  _step = none;
  _comment = none;
}

main() {
  examples = [
    Example( -2,  2,  1, "Normal" ),
    Example(  2,  2,  0, "Start equal stop: zero increment" ),
    Example(  0,  0,  0, "Start equal stop equal zero: zero increment" ),
    Example(  2,  2,  1, "Start equal stop: positive increment" ),
    Example(  2,  2, -1, "Start equal stop: negative increment" ),
    Example( -2,  2, 10, "First increment is beyond stop value" ),
    Example( -2,  2,  0, "Zero increment, stop greater than start" ),
    Example( -2,  2, -1, "Increments away from stop value" ),
    Example(  2, -2,  1, "Start more than stop: positive increment" )
  ];
  for ( ex : examples ) {
    print(
      "{}\nRange( {}, {}, {} ) -> ".format(
        ex._comment, ex._start, ex._stop, ex._step
      )
    );
    r = algo.range( ex._start, ex._stop, ex._step );
    print(
      "{}\n\n".format(
        algo.materialize( algo.slice( r, 22 ), list )
      )
    );
  }
}


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

public class LoopsWrongRanges {

    public static void main(String[] args) {
        runTest(new LoopTest(-2, 2, 1, "Normal"));
        runTest(new LoopTest(-2, 2, 0, "Zero increment"));
        runTest(new LoopTest(-2, 2, -1, "Increments away from stop value"));
        runTest(new LoopTest(-2, 2, 10, "First increment is beyond stop value"));
        runTest(new LoopTest(2, -2, 1, "Start more than stop: positive increment"));
        runTest(new LoopTest(2, 2, 1, "Start equal stop: positive increment"));
        runTest(new LoopTest(2, 2, -1, "Start equal stop: negative increment"));
        runTest(new LoopTest(2, 2, 0, "Start equal stop: zero increment"));
        runTest(new LoopTest(0, 0, 0, "Start equal stop equal zero: zero increment"));
    }

    private static void runTest(LoopTest loopTest) {
        List<Integer> values = new ArrayList<>();
        for (int i = loopTest.start ; i <= loopTest.stop ; i += loopTest.increment ) {
            values.add(i);
            if ( values.size() >= 10 ) {
                break;
            }
        }
        System.out.printf("%-45s %s%s%n", loopTest.comment, values, values.size()==10 ? " (loops forever)" : "");
    }

    private static class LoopTest {
        int start;
        int stop;
        int increment;
        String comment;
        public LoopTest(int start, int stop, int increment, String comment) {
            this.start = start;
            this.stop = stop;
            this.increment = increment;
            this.comment = comment;
        }
    }

}


sub luck(\a,\b) {
    gather {
	my @taken = take a;
	my @rotor;
	my $i = b;

	loop {
	    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, $i - @taken;
	    }
	    $i += 2;
	}
    }
}

constant @lucky = luck(1,3);
constant @evenlucky = luck(2,4);

subset Luck where m:i/^ 'even'? 'lucky' $/;

multi MAIN (Int $num where * > 0) {
    say @lucky[$num-1];
}

multi MAIN (Int $num where * > 0, ',', Luck $howlucky = 'lucky') {
    say @::(lc $howlucky)[$num-1];
}

multi MAIN (Int $first where * > 0, Int $last where * > 0, Luck $howlucky = 'lucky') {
    say @::(lc $howlucky)[$first-1 .. $last - 1];
}

multi MAIN (Int $min where * > 0, Int $neg-max where * < 0, Luck $howlucky = 'lucky') {
    say grep * >= $min, (@::(lc $howlucky) ...^ * > abs $neg-max);
}


*        Lucas-Lehmer test
LUCASLEH CSECT
         USING  LUCASLEH,R12
SAVEARA  B      STM-SAVEARA(R15)
         DC     17F'0'
         DC     CL8'LUCASLEH'
STM      STM    R14,R12,12(R13) save calling context
         ST     R13,4(R15)
         ST     R15,8(R13)
         LR     R12,R15         set addessability
*        ----   CODE
         LA     R2,2            R2=2
         LA     R11,0           R11:N'
         BCTR   R11,0           N':=X'FFFFFFFF'
         LA     R10,1           R10:N N=1
         LA     R4,1            R4:IEXP
         LA     R6,1            step
         LH     R7,IEXPMAX      R7:IEXPMAX limit
LOOPE    BXH    R4,R6,ENDLOOPE	do iexp=2 to iexpmax
         SR     R3,R3           R3:S S=0
         CR     R4,R2           if iexp=2 then S=0
         BE     OKS
         LA     R3,4            else S=4
OKS      EQU    *
         SLDA   R10,1           n=(n+1)*2-1
         LA     R5,0            I
         LA     R8,1            step
         LR     R9,R4           IEXP
         SR     R9,R2           IEXP-2 limit
LOOPI    BXH    R5,R8,ENDLOOPI	do i=1 to iexp-2
*        ----   compute s=(s*s-2) MOD n
         SR     R14,R14         R14=0
         LR     R15,R3          R15=S
         MR     R14,R3          R{14-15}=S*S
         SLR    R15,R2          R15=R15-2=S*S-2
         BNM    *+6             skip next if no borrow
         BCTR   R14,0           perform borrow
         DR     R14,R10         R10=N
         LR     R3,R14          R14=MOD
         B      LOOPI
ENDLOOPI EQU    *
         LTR    R3,R3
         BNZ    NOPRT           if s<>0 then no print
         CVD    R4,P            store to packed P
         UNPK   Z,P             Z=P
         MVC    C,Z             C=Z
         OI     C+L'C-1,X'F0'   zap sign
         MVC    WTOBUF(4),C+12
         MVI    WTOBUF,C'M'
         WTO    MF=(E,WTOMSG)
NOPRT    EQU    *
         B      LOOPE
ENDLOOPE EQU    *
*        ----   END CODE
RETURN   EQU    *
         LM     R14,R12,12(R13)
         XR     R15,R15
         BR     R14
*        ----   DATA
IEXPMAX  DC     H'31'
I        DS     H
IEXP     DS     H
S        DS     F
N        DS     F
P        DS     PL8             packed
Z        DS     ZL16            zoned
C        DS     CL16            character
WTOMSG   DS     0F
         DC     H'80',XL2'0000'
WTOBUF   DC     80C' '
         LTORG
         YREGS
         END    LUCASLEH


with Ada.Text_Io; use Ada.Text_Io;
with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;

procedure Lucas_Lehmer_Test is
   type Ull is mod 2**64;
   function Mersenne(Item : Integer) return Boolean is
      S : Ull := 4;
      MP : Ull := 2**Item - 1;
   begin
      if Item = 2 then
         return True;
      else
         for I in 3..Item loop
            S := (S * S - 2) mod MP;
         end loop;
         return S = 0;
      end if;
   end Mersenne;
   Upper_Bound : constant Integer := 64;
begin
   Put_Line(" Mersenne primes:");
   for P in 2..Upper_Bound loop
      if Mersenne(P) then
         Put(" M");
         Put(Item => P, Width => 1);
      end if;
   end loop;
end Lucas_Lehmer_Test;


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

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

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

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

    numbers
}

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

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

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

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

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

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

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

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

/// Prints triplets until a certain Ludic number.
fn print_triplets_until(ludics: &[usize], limit: usize) {
    for (number, triplet_2, triplet_3) in triplets_below(ludics, limit) {
        println!("{} {} {}", number, triplet_2, triplet_3);
    }
}


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


// Version 1.2.70

class Example(val start: Int, val stop: Int, val incr: Int, val comment: String)

var examples = listOf(
    Example(-2, 2, 1, "Normal"),
    Example(-2, 2, 0, "Zero increment"),
    Example(-2, 2, -1, "Increments away from stop value"),
    Example(-2, 2, 10, "First increment is beyond stop value"),
    Example(2, -2, 1, "Start more than stop: positive increment"),
    Example(2, 2, 1, "Start equal stop: positive increment"),
    Example(2, 2, -1, "Start equal stop: negative increment"),
    Example(2, 2, 0, "Start equal stop: zero increment"),
    Example(0, 0, 0, "Start equal stop equal zero: zero increment")
)

fun sequence(ex: Example, limit: Int) =
    if (ex.incr == 0) {
        List(limit) { ex.start }
    }
    else {
        val res = mutableListOf<Int>()
        var c = 0
        var i = ex.start
        while (i <= ex.stop && c < limit) {
            res.add(i)
            i += ex.incr
            c++
        }
        res
    }

fun main(args: Array<String>) {
    for (ex in examples) {
        println(ex.comment)
        System.out.printf("Range(%d, %d, %d) -> ", ex.start, ex.stop, ex.incr)
        println(sequence(ex, 10))
        println()
    }
}


/*REXX program displays  lucky  or  evenLucky  integers   (numbers  or  a number range).*/
parse arg bot top func _ .                       /*obtain required & optional arguments.*/
if func==''  then func= 'lucky'                  /*Not specified?  Then use the default.*/
s= left('s', bot\==top  &  top\==",")            /*plural results (or maybe not plural).*/
say func  'number's":"   bot  top   '───►'   $lucky(bot, top, func, _)
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
$lucky: arg x,y,f,?;   if y=='' | y==","  then y= x      /*obtain some arguments; set Y.*/
        #= 0;          $=;                    ny= y<0    /*set variable NOY: value range*/
        if f==''  then f= 'LUCKY';   lucky= (f=="LUCKY") /*assume  LUCKY  if omitted.   */
        if f\=='LUCKY' & f\=='EVENLUCKY'  then return  'function not valid: '     f
        if arg()>3  &  ?\=''      then return  "too many arguments entered: "     ?
        if x=''                   then return  "1st argument is missing."
        if x<1                    then return  "1st argument isn't a positive integer: " x
        if \datatype(x,'W')       then return  "1st argument isn't an integer: "  x
        if \datatype(y,'W')       then return  "2nd argument isn't an integer: "  y
        if x>ay                   then return  "2nd argument is less than 1st arg."
        ay=abs(y); yL=ay; if y>0  then yL= y*10  + y + y /*adjust the upper  Y  limit.  */
                                                         /* [↓]  build LUCKY | EVENLUCKY*/
            do j=1  until j>=yL                          /*construct list pos. integers.*/
            if j//2==(\lucky)  then iterate              /*EVENLUCKY? Use only even ints*/

            if lucky  then if (j+1)//6==0  then iterate  /*prune       if  mod 6 ≡ zero.*/
                                           else nop      /*balance the   IF-THEN  logic.*/
                      else if  j   //8==0  then iterate  /*prune next  if  mod 8 ≡ zero.*/
            #= # + 1                                     /*bump the counter of numbers. */
            $= $ j                                       /*append integer to the $ list.*/
            end   /*j*/
        q=0
            do p=3  until  q=='';       q= word($, p)    /*start to prune  integer list.*/
            if q>#  then leave                           /*if integer is too large, stop*/
                                do j=#%q*q  by -q  to q  /*elide every  Qth  integer.   */
                                $= delword($, j, 1)      /*delete a particular number.  */
                                #= # -1                  /*decrease the integer count.  */
                                end   /*j*/              /*delete from the right side.  */
            end   /*p*/
        @.=
                  do k=1;  parse var $ q $;       if q==''  then leave;       @.k= q
                  end   /*k*/
        @.0=k-1
                  do m=1  for #                          /*restrict the found integers. */
                  if (\ny  &  (m<x  |  m>ay))  |  (ny  &  (@.m<x | @.m>ay))  then @.m=
                  end   /*m*/                            /* [↑]  a list of #s or a range*/
        _=
                  do b=1  for @.0;     _= _ @.b          /*construct a list of integers.*/
                  end   /*b*/
        return space(_)                                  /*remove superfluous blanks.   */


readlib 'mapm';

mapm.xdigits(100);

mersenne := proc(p::number) is
   local s, m;
   s := 4;
   m := mapm.xnumber(2^p) - 1;
   if p = 2 then
      return true
   else
      for i from 3 to p do
         s := (mapm.xnumber(s)^2 - 2) % m
      od;
      return mapm.xtoNumber(s) = 0
   fi
end;

for i from 3 to 64 do
   if mersenne(i) then
      write('M' & i & ' ')
   fi
od;


PRAGMAT stack=1M precision=20000 PRAGMAT

PROC is prime = ( INT p )BOOL:
  IF p = 2 THEN TRUE
  ELIF p <= 1 OR p MOD 2 = 0 THEN FALSE
  ELSE
    BOOL prime := TRUE;
    FOR i FROM 3 BY 2 TO ENTIER sqrt(p)
      WHILE prime := p MOD i /= 0 DO SKIP OD;
    prime
  FI;

PROC is mersenne prime = ( INT p )BOOL:
  IF p = 2 THEN TRUE
  ELSE
    LONG LONG INT m p :=  LONG LONG 2 ** p - 1, s := 4;
    FROM 3 TO p DO
      s := (s ** 2 - 2) MOD m p
    OD;
    s = 0
  FI;

test:(
  INT upb prime = ( long long bits width - 1 ) OVER 2; # no unsigned #
  INT upb count = 45; # find 45 mprimes if INT has enough bits #

  printf(($" Finding Mersenne primes in M[2.."g(0)"]: "l$,upb prime));

  INT count:=0;
  FOR p FROM 2 TO upb prime WHILE
    IF is prime(p) THEN
      IF is mersenne prime(p) THEN
        printf (($" M"g(0)$,p));
        count +:= 1
      FI
    FI;
    count <= upb count
  DO SKIP OD
)


$ 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;


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


val .data = q:block END
    start     stop     increment     comment
    -2        2        1             Normal
    -2        2        0             Zero increment
    -2        2        -1            Increments away from stop value
    -2        2        10            First increment is beyond stop value
    2         -2       1             Start more than stop: positive increment
    2         2        1             Start equal stop: positive increment
    2         2        -1            Start equal stop: negative increment
    2         2        0             Start equal stop: zero increment
    0         0        0             Start equal stop equal zero: zero increment
END

var .table = submatches(RE/([^ ]+) +([^ ]+) +([^ ]+) +(.+)\n?/, .data)
val .f = toNumber
for .i in 2..len(.table) {
    .table[.i] = map [.f, .f, .f, _], .table[.i]
}

for .test in rest(.table) {
    val .start, .stop, .inc, .comment = .test
    {
        val .series = series(.start to .stop, .inc)
        catch {
            writeln $"\.comment;\nERROR: \._err["msg"]:L200(...);\n"
        } else {
            writeln $"\.comment;\nresult: \.series;\n"
        }
    }
}


# Normal
seq(-2..2, 1);

# Zero increment
seq(-2..2, 0);

# Increments away from stop value
seq(-2..2, -1);

# First increment is beyond stop value
seq(-2..2, 10);

# Start more than stop: positive increment
seq(2..-2, 1);

# Start equal stop: positive increment
seq(2..2, 1);

# Start equal stop: negative increment
seq(2..2, -1);

# Start equal stop: zero increment
seq(2..2, 0);

# Start equal stop equal zero: zero increment
seq(0..0, 0);


import sequtils, strformat

proc displayRange(first, last, step: int) =

  stdout.write &"({first:>2}, {last:>2}, {step:>2}):   "

  echo if step > 0: ($toSeq(countup(first, last, step)))[1..^1]
       elif step < 0: ($toSeq(countdown(first, last, -step)))[1..^1]
       else: "not allowed."

for (f, l, s) in [(-2, 2, 1), (-2, 2, 0), (-2, 2, -1),
                  (-2, 2, 10), (2, -2, 1), (2, 2, 1),
                  (2, 2, -1), (2, 2, 0), (0, 0, 0)]:
  displayRange(f, l, s)


for $i (
     [ -2,    2,    1], #1 Normal
     [ -2,    2,    0], #2 Zero increment
     [ -2,    2,   -1], #3 Increments away from stop value
     [ -2,    2,   10], #4 First increment is beyond stop value
     [  2,   -2,    1], #5 Start more than stop: positive increment
     [  2,    2,    1], #6 Start equal stop: positive increment
     [  2,    2,   -1], #7 Start equal stop: negative increment
     [  2,    2,    0], #8 Start equal stop: zero increment
     [  0,    0,    0], #9 Start equal stop equal zero: zero increment
) {
    $iter = gen_seq(@$i);
    printf "start: %3d  stop: %3d  incr: %3d | ", @$i;
    printf "%4s", &$iter for 1..10;
    print "\n";
}

sub gen_seq {
    my($start,$stop,$increment) = @_;
    $n = 0;
    return sub {
        $term = $start + $n++ * $increment;
        return $term > $stop ? '' : $term;
    }
}


# Project : Lucky and even lucky numbers

lucky = list(50)
dellucky = []
for n = 1 to 50
     lucky[n] = 2*n-1
next
see "the first 20 lucky numbers:" + nl
luckynumbers(lucky)
showarray(lucky)
see nl

lucky = list(50)
dellucky = []
for n = 1 to 50
     lucky[n] = 2*n
next
see "the first 20 even lucky numbers:" + nl
luckynumbers(lucky)
showarray(lucky)
see nl

lucky = list(20000)
dellucky = []
for n = 1 to 10000
     lucky[n] = 2*n-1
next
see "lucky numbers between 6,000 and 6,100:" + nl
luckynumbers2(lucky)
showarray2(lucky)
see nl

lucky = list(20000)
dellucky = []
for n = 1 to 10000
     lucky[n] = 2*n
next
see "even lucky numbers between 6,000 and 6,100:" + nl
luckynumbers2(lucky)
showarray2(lucky)
see nl

func luckynumbers(lucky)
      for n = 2 to len(lucky)
          dellucky = []
          for m = lucky[n] to len(lucky) step lucky[n]
              add(dellucky, m)
          next
          for p = len(dellucky)  to 1 step -1
              del(lucky, dellucky[p])
          next
      next

func luckynumbers2(lucky)
      for n = 2 to len(lucky)
          dellucky = []
          for m = lucky[n] to len(lucky) step lucky[n]
              add(dellucky, m)
          next
          for p = len(dellucky)  to 1 step -1
              del(lucky, dellucky[p])
          next
          if lucky[n] >= 6100
             exit
          ok
next

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

func showarray2(vect)
      see "["
      svect = ""
      for n = 1 to len(vect)
          if vect[n] >= 6000 and vect[n] <= 6100
             svect = svect + vect[n] + ", "
          ok
      next
      svect = left(svect, len(svect) - 2)
      see svect
      see "]" + nl


def generator(even=false, nmax=1000000)
  start = even ? 2 : 1
  Enumerator.new do |y|
    n = 1
    ary = [0] + (start..nmax).step(2).to_a      # adds [0] to revise the 0 beginnings.
    y << ary[n]
    while (m = ary[n+=1]) < ary.size
      y << m
      (m...ary.size).step(m){|i| ary[i]=nil}
      ary.compact!                              # remove nil
    end
    # drain
    ary[n..-1].each{|i| y << i}
    raise StopIteration
  end
end

def lucky(argv)
  j, k = argv[0].to_i, argv[1].to_i
  mode = /even/i=~argv[2] ? :'even lucky' : :lucky
  seq = generator(mode == :'even lucky')
  ord = ->(n){"#{n}#{(n%100).between?(11,19) ? 'th' : %w[th st nd rd th th th th th th][n%10]}"}
  if k.zero?
    puts "#{ord[j]} #{mode} number: #{seq.take(j).last}"
  elsif 0 < k
    puts "#{ord[j]} through #{ord[k]} (inclusive) #{mode} numbers",
         "  #{seq.take(k)[j-1..-1]}"
  else
    k = -k
    ary = []
    loop do
      case num=seq.next
      when 1...j
      when j..k  then ary << num
      else break
      end
    end
    puts "all #{mode} numbers in the range #{j}..#{k}",
         "  #{ary}"
  end
end

if __FILE__ == $0
  lucky(ARGV)
end


/* ARM assembly Raspberry PI  */
/*  program lucaslehmer.s   */
/* use library gmp     */
/* link with gcc option -lgmp */

/* Constantes    */
.equ STDOUT, 1                           @ Linux output console
.equ EXIT,   1                           @ Linux syscall
.equ WRITE,  4                           @ Linux syscall

.equ NBRECH,          30

/* Initialized data */
.data
szMessResult:       .ascii "Prime : M"
sMessValeur:        .fill 11, 1, ' '            @ size => 11
                    .asciz "\n"

szCarriageReturn:   .asciz "\n"
szformat:           .asciz "nombre= %Zd\n"

/* UnInitialized data */
.bss
.align 4
spT:                .skip 100
mpT:                .skip 100
Deux:               .skip 100
snT:                .skip 100
/*  code section */
.text
.global main
main:
    ldr r0,iAdrDeux                       @ create big number = 2
    mov r1,#2
    bl __gmpz_init_set_ui
    ldr r0,iAdrspT                        @ init big number
    bl __gmpz_init
    ldr r0,iAdrmpT                        @ init big number
    bl __gmpz_init
    mov r5,#3                             @ start number
    mov r6,#0                             @ result counter
1:
    ldr r0,iAdrspT                        @ conversion integer in big number gmp
    mov r1,r5
    bl __gmpz_set_ui
    ldr r0,iAdrspT                        @ control if exposant is prime !
    ldr r0,iAdrspT
    mov r1,#25
    bl __gmpz_probab_prime_p
    cmp r0,#0
    beq 5f

2:
    //ldr r1,iAdrspT                      @ example number display
    //ldr r0,iAdrszformat
    //bl __gmp_printf
/******** Compute (2 pow p) - 1   ******/
    ldr r0,iAdrmpT                        @ compute 2 pow p
    ldr r1,iAdrDeux
    mov r2,r5
    bl __gmpz_pow_ui
    ldr r0,iAdrmpT
    ldr r1,iAdrmpT
    mov r2,#1
    bl __gmpz_sub_ui                      @ then (2 pow p) - 1

    ldr r0,iAdrsnT
    mov r1,#4
    bl __gmpz_init_set_ui                 @ init big number with 4

/**********  Test lucas_lehner  *******/
    mov r4,#2                             @ loop counter
3:                                        @ begin loop
    ldr r0,iAdrsnT
    ldr r1,iAdrsnT
    mov r2,#2
    bl __gmpz_pow_ui                      @ compute square big number

    ldr r0,iAdrsnT
    ldr r1,iAdrsnT
    mov r2,#2
    bl __gmpz_sub_ui                      @ = (sn *sn) - 2

    ldr r0,iAdrsnT                        @ compute remainder -> sn
    ldr r1,iAdrsnT                        @ sn
    ldr r2,iAdrmpT                        @ p
    bl __gmpz_tdiv_r

    //ldr r1,iAdrsnT                      @ display number for control
    //ldr r0,iAdrszformat
    //bl __gmp_printf

    add r4,#1                             @ increment counter
    cmp r4,r5                             @ end ?
    blt 3b                                @ no -> loop
                                          @ compare result with zero
    ldr r0,iAdrsnT
    mov r1,#0
    bl __gmpz_cmp_d
    cmp r0,#0
    bne 5f
/********* is prime display result      *********/
    mov r0,r5
    ldr r1,iAdrsMessValeur                @ display value
    bl conversion10                       @ call conversion decimal
    ldr r0,iAdrszMessResult               @ display message
    bl affichageMess
    add r6,#1                             @ increment counter result
    cmp r6,#NBRECH
    bge 10f
5:
    add r5,#2                             @ increment number by two
    b 1b                                  @ and loop

10:
    ldr r0,iAdrDeux                       @ clear memory big number
    bl __gmpz_clear
    ldr r0,iAdrsnT
    bl __gmpz_clear
    ldr r0,iAdrmpT
    bl __gmpz_clear
    ldr r0,iAdrspT
   bl __gmpz_clear
100:                                      @ standard end of the program
    mov r0, #0                            @ return code
    mov r7, #EXIT                         @ request to exit program
    svc 0                                 @ perform system call
iAdrszMessResult:         .int szMessResult
iAdrsMessValeur:          .int sMessValeur
iAdrszCarriageReturn:     .int szCarriageReturn
iAdrszformat:             .int szformat
iAdrspT:                  .int spT
iAdrmpT:                  .int mpT
iAdrDeux:                 .int Deux
iAdrsnT:                  .int snT
/******************************************************************/
/*     display text with size calculation                         */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
    push {r0,r1,r2,r7,lr}                       @ save  registers
    mov r2,#0                                   @ counter length */
1:                                              @ loop length calculation
    ldrb r1,[r0,r2]                             @ read octet start position + index
    cmp r1,#0                                   @ if 0 its over
    addne r2,r2,#1                              @ else add 1 in the length
    bne 1b                                      @ and loop
                                                @ so here r2 contains the length of the message
    mov r1,r0                                   @ address message in r1
    mov r0,#STDOUT                              @ code to write to the standard output Linux
    mov r7, #WRITE                              @ code call system "write"
    svc #0                                      @ call system
    pop {r0,r1,r2,r7,lr}                        @ restaur registers
    bx lr                                       @ return
/******************************************************************/
/*     Converting a register to a decimal unsigned                */
/******************************************************************/
/* r0 contains value and r1 address area   */
/* r0 return size of result (no zero final in area) */
/* area size => 11 bytes          */
.equ LGZONECAL,   10
conversion10:
    push {r1-r4,lr}                                 @ save registers
    mov r3,r1
    mov r2,#LGZONECAL

1:                                                  @ start loop
    bl divisionpar10U                               @ unsigned  r0 <- dividende. quotient ->r0 reste -> r1
    add r1,#48                                      @ digit
    strb r1,[r3,r2]                                 @ store digit on area
    cmp r0,#0                                       @ stop if quotient = 0
    subne r2,#1                                     @ else previous position
    bne 1b                                          @ and loop
                                                    @ and move digit from left of area
    mov r4,#0
2:
    ldrb r1,[r3,r2]
    strb r1,[r3,r4]
    add r2,#1
    add r4,#1
    cmp r2,#LGZONECAL
    ble 2b
                                                      @ and move spaces in end on area
    mov r0,r4                                         @ result length
    mov r1,#' '                                       @ space
3:
    strb r1,[r3,r4]                                   @ store space in area
    add r4,#1                                         @ next position
    cmp r4,#LGZONECAL
    ble 3b                                            @ loop if r4 <= area size

100:
    pop {r1-r4,lr}                                    @ restaur registres
    bx lr                                             @return

/***************************************************/
/*   division par 10   unsigned                    */
/***************************************************/
/* r0 dividende   */
/* r0 quotient */
/* r1 remainder  */
divisionpar10U:
    push {r2,r3,r4, lr}
    mov r4,r0                                          @ save value
    //mov r3,#0xCCCD                                   @ r3 <- magic_number lower  raspberry 3
    //movt r3,#0xCCCC                                  @ r3 <- magic_number higter raspberry 3
    ldr r3,iMagicNumber                                @ r3 <- magic_number    raspberry 1 2
    umull r1, r2, r3, r0                               @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0)
    mov r0, r2, LSR #3                                 @ r2 <- r2 >> shift 3
    add r2,r0,r0, lsl #2                               @ r2 <- r0 * 5
    sub r1,r4,r2, lsl #1                               @ r1 <- r4 - (r2 * 2)  = r4 - (r0 * 10)
    pop {r2,r3,r4,lr}
    bx lr                                              @ leave function
iMagicNumber:  	.int 0xCCCCCCCD


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


procedure test(integer start, stop, step, string legend, bool bFor)
    sequence res = {}
    if bFor then
        try
            for i=start to stop by step do
                res &= i
                if length(res)>9 then exit end if
            end for
            res = sprint(res)
        catch e
            res = e[E_USER]
        end try
    else
        integer i = start
        while (step>=0 and i<=stop)
           or (step<=0 and i>=stop) do
            res &= i
            if length(res)>9 then exit end if
--          if i=stop then exit end if
--          if step=0 then exit end if
            i += step
        end while
        res = sprint(res)
    end if
    printf(1,"%-43s: %s\n",{legend,res})
end procedure

for i=1 to 2 do
    ?iff(i=1?"for":"while")
    test(-2, 2, 1, "Normal"                                     ,i=1)
    test(-2, 2, 0, "Zero increment"                             ,i=1)
    test(-2, 2,-1, "Increments away from stop value"            ,i=1)
    test(-2, 2,10, "First increment is beyond stop value"       ,i=1)
    test( 2,-2, 1, "Start more than stop: positive increment"   ,i=1)
    test( 2, 2, 1, "Start equal stop: positive increment"       ,i=1)
    test( 2, 2,-1, "Start equal stop: negative increment"       ,i=1)
    test( 2, 2, 0, "Start equal stop: zero increment"           ,i=1)
    test( 0, 0, 0, "Start equal stop equal zero: zero increment",i=1)
    puts(1,"\n")
end for


struct LuckyNumbers : Sequence, IteratorProtocol {
  let even: Bool
  let through: Int

  private var drainI = 0
  private var n = 0
  private var lst: [Int]

  init(even: Bool = false, through: Int = 1_000_000) {
    self.even = even
    self.through = through
    self.lst = Array(stride(from: even ? 2 : 1, through: through, by: 2))
  }

  mutating func next() -> Int? {
    guard n != 0 else {
      defer { n += 1 }

      return lst[0]
    }

    while n < lst.count && lst[n] < lst.count {
      let retVal = lst[n]

      lst = lst.enumerated().filter({ ($0.offset + 1) % lst[n] != 0  }).map({ $0.element })
      n += 1

      return retVal
    }

    if drainI == 0 {
      lst = Array(lst.dropFirst(n))
    }

    while drainI < lst.count {
      defer { drainI += 1 }

      return lst[drainI]
    }

    return nil
  }
}


#!/usr/bin/env tclsh8.6
package require Tcl 8.6

proc lgen {{even false} {nmax 200000}} {
    coroutine lgen.[incr ::lgen] apply {{start nmax} {
	set n 1
	for {set i $start} {$i <= $nmax+1} {incr i 2} {lappend lst $i}
	yield [info coroutine]
	yield [lindex $lst 0]
	while {$n < [llength $lst] && [lindex $lst $n] < [llength $lst]} {
	    yield [lindex $lst $n]
	    set lst [set i 0;lmap j $lst {
		if {[incr i] % [lindex $lst $n]} {set j} else continue
	    }]
	    incr n
	}
	foreach i [lrange $lst $n end] {
	    yield $i
	}
    }} [expr {$even ? 2 : 1}] $nmax
}

proc collectIndices {generator from to} {
    set result {}
    for {set i 0} {$i <= $to} {incr i} {
	set n [$generator]
	if {$i >= $from} {lappend result $n}
    }
    rename $generator {}
    return $result
}
proc collectValues {generator from to} {
    set result {}
    while 1 {
	set n [$generator]
	if {$n > $to} break
	if {$n >= $from} {lappend result $n}
    }
    rename $generator {}
    return $result
}

if {$argc<1||$argc>3} {
    puts stderr "wrong # args: should be \"$argv0 from ?to? ?evenOdd?\""
    exit 1
}
lassign $argv from to evenOdd
if {$argc < 3} {set evenOdd lucky}
if {$argc < 2} {set to ,}
if {![string is integer -strict $from] || $from < 1} {
    puts stderr "\"from\" must be positive integer"
    exit 1
} elseif {$to ne "," && (![string is integer -strict $to] || $to == 0)} {
    puts stderr "\"to\" must be positive integer or comma"
    exit 1
} elseif {[set evenOdd [string tolower $evenOdd]] ni {lucky evenlucky}} {
    puts stderr "\"evenOdd\" must be \"lucky\" or \"evenLucky\""
    exit 1
}
set l [lgen [expr {$evenOdd eq "evenlucky"}]]
set evenOdd [lindex {"lucky" "even lucky"} [expr {$evenOdd eq "evenlucky"}]]
if {$to eq ","} {
    puts "$from'th $evenOdd number = [collectIndices $l [incr from -1] $from]"
} elseif {$to < 0} {
    set to [expr {-$to}]
    puts "all $evenOdd numbers from $from to $to: [join [collectValues $l $from $to] ,]"
} else {
    puts "$from'th to $to'th $evenOdd numbers: [join [collectIndices $l [incr from -1] [incr to -1]] ,]"
}


mersenne?: function [p][
    if p=2 -> return true
    mp: dec shl 1 p
    s: 4
    loop 3..p 'i ->
        s: (sub s*s 2) % mp
    return s=0
]

print "Mersenne primes:"
mersennes: select 2..32 'x -> and? prime? x mersenne? x
print join.with:", " map mersennes 'm -> ~"M|m|"


# syntax: GAWK -f LUCAS-LEHMER_TEST.AWK
# converted from Pascal
BEGIN {
    printf("Mersenne primes:")
    n = 1
    for (exponent=2; exponent<=32; exponent++) {
      s = (exponent == 2) ? 0 : 4
      n = (n+1)*2-1
      for (i=1; i<=exponent-2; i++) {
        s = (s*s-2)%n
      }
      if (s == 0) {
        printf(" M%s",exponent)
      }
    }
    printf("\n")
    exit(0)
}


open List;

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

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

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


loops:procedure options (main);
   declare i fixed binary;

   put skip list ('-2 to 2 by  1:');
   do i = -2 to 2 by 1;
      put edit (i) (f(3));
   end;
   put skip list ('-2 to 2 by  0: infinite loop, prints -2');

   put skip list ('-2 to 2 by -1: [no values printed]');
   do i = -2 to 2 by -1;
      put edit (i) (f(3));
   end;

   put skip list ('-2 to 2 by 10:');
   do i = -2 to 2 by 1;
      put edit (i) (f(3));
   end;

   put skip list (' 2 to 2 by  1:');
   do i = 2 to 2 by 1;
      put edit (i) (f(3));
   end;

   put skip list (' 2 to 2 by -1:');
   do i = 2 to 2 by -1;
      put edit (i) (f(3));
   end;

   put skip list (' 2 to 2 by  0: infinite loop, prints 2');
   put skip list (' 0 to 0 by  0: infinite loop, prints 0');

end loops;


import re
from itertools import islice # To limit execution if it would generate huge values
# list(islice('ABCDEFG', 2)) --> ['A', 'B']
# list(islice('ABCDEFG', 4)) --> ['A', 'B', 'C', 'D']

data = '''
start 	stop 	increment 	Comment
-2 	2 	1 	Normal
-2 	2 	0 	Zero increment
-2 	2 	-1 	Increments away from stop value
-2 	2 	10 	First increment is beyond stop value
2 	-2 	1 	Start more than stop: positive increment
2 	2 	1 	Start equal stop: positive increment
2 	2 	-1 	Start equal stop: negative increment
2 	2 	0 	Start equal stop: zero increment
0 	0 	0 	Start equal stop equal zero: zero increment
'''

table = [re.split(r'\s\s+', line.strip()) for line in data.strip().split('\n')]
#%%
for _start, _stop, _increment, comment in table[1:]:
    start, stop, increment = [int(x) for x in (_start, _stop, _increment)]
    print(f'{comment.upper()}:\n  range({start}, {stop}, {increment})')
    values = None
    try:
        values = list(islice(range(start, stop, increment), 999))
    except ValueError as e:
        print('  !!ERROR!!', e)
    if values is not None:
        if len(values) < 22:
            print('    =', values)
        else:
            print('    =', str(values[:22])[:-1], '...')


seq(from = -2, to = 2, by = 1)#Output: -2 -1  0  1  2
seq(from = -2, to = 2, by = 0)#Fails: "invalid '(to - from)/by'"
seq(from = -2, to = 2, by = -1)#Fails: As in the notes above - "Specifying to - from and by of opposite signs is an error."
seq(from = -2, to = 2, by = 10)#Output: -2
seq(from = 2, to = -2, by = 1)#Fails: Same as the third case.
seq(from = 2, to = 2, by = 1)#Output: 2
seq(from = 2, to = 2, by = -1)#Output: 2
seq(from = 2, to = 2, by = 0)#Output: 2
seq(from = 0, to = 0, by = 0)#Output: 0


import "os" for Process
import "/trait" for Stepped
import "/str" for Str

var luckyOdd  = List.filled(1e5, 0)
var luckyEven = List.filled(1e5, 0)

var init = Fn.new {
    for (i in 0...1e5) {
        luckyOdd[i]  = i*2 + 1
        luckyEven[i] = i*2 + 2
    }
}

var filterLuckyOdd = Fn.new {
    var n = 2
    while (n < luckyOdd.count) {
        var m = luckyOdd[n-1]
        var end = (luckyOdd.count/m).floor * m - 1
        for (j in Stepped.descend(end..m-1, m)) luckyOdd.removeAt(j)
        n = n + 1
    }
}

var filterLuckyEven = Fn.new {
    var n = 2
    while (n < luckyEven.count) {
        var m = luckyEven[n-1]
        var end = (luckyEven.count/m).floor * m - 1
        for (j in Stepped.descend(end..m-1, m)) luckyEven.removeAt(j)
        n = n + 1
    }
}

var printSingle = Fn.new { |j, odd|
    if (odd) {
        if (j >= luckyOdd.count) Fiber.abort("Argument is too big")
        System.print("Lucky number %(j) = %(luckyOdd[j-1])")
    } else {
        if (j >= luckyEven.count) Fiber.abort("Argument is too big")
        System.print("Lucky even number %(j) = %(luckyEven[j-1])")
    }
}

var printRange = Fn.new { |j, k, odd|
    if (odd) {
        if (k >= luckyOdd.count) Fiber.abort("Argument is too big")
        var rng = luckyOdd.skip(j-1).take(k-j+1).toList
        System.print("Lucky numbers %(j) to %(k) are:\n %(rng)")
    } else {
        if (k >= luckyEven.count) Fiber.abort("Argument is too big")
        var rng = luckyEven.skip(j-1).take(k-j+1).toList
        System.print("Lucky even numbers %(j) to %(k) are:\n %(rng)")
    }
}

var printBetween = Fn.new { |j, k, odd|
    var rng = []
    if (odd) {
        var max = luckyOdd[-1]
        if (j > max || k > max) {
            Fiber.abort("At least one argument is too big")
        }
        for (num in luckyOdd) {
            if (num >= j) {
                if (num > k) break
                rng.add(num)
            }
        }
        System.print("Lucky numbers between %(j) and %(k) are:\n%(rng)")
    } else {
        var max = luckyEven[-1]
        if (j > max || k > max) {
            Fiber.abort("At least one argument is too big")
        }
        for (num in luckyEven) {
            if (num >= j) {
                if (num > k) break
                rng.add(num)
            }
        }
        System.print("Lucky even numbers between %(j) and %(k) are:\n%(rng)")
    }
}

var args = Process.arguments
var argsSize = args.count
if (argsSize < 1 || argsSize > 3) Fiber.abort("There must be between 1 and 3 command line arguments")
init.call()
filterLuckyOdd.call()
filterLuckyEven.call()
var j = Num.fromString(args[0])
if (j.type != Num || !j.isInteger || j < 1) Fiber.abort("First argument must be a positive integer")
if (argsSize == 1) {
    printSingle.call(j, true)
    return
}

if (argsSize == 2) {
    var k = Num.fromString(args[1])
    if (k.type != Num || !k.isInteger) Fiber.abort("Second argument must be an integer")
    if (k >= 0) {
        if (j > k) Fiber.abort("Second argument can't be less than first")
        printRange.call(j, k, true)
    } else {
        var l = -k
        if (j > l) Fiber.abort("The second argument can't be less in absolute value than first")
        printBetween.call(j, l, true)
    }
    return
}

args[2] = Str.lower(args[2])
var odd = (args[2] == "lucky") ? true :
          (args[2] == "evenlucky") ? false : Fiber.abort("Third argument is invalid")

if (args[1] == ",") {
    printSingle.call(j, odd)
    return
}

var k = Num.fromString(args[1])
if (!((k.type == Num && k.isInteger) || (k.type == String && k == ","))) {
    Fiber.abort("Second argument must be an integer or a comma")
}
if (k >= 0) {
    if (j > k) Fiber.abort("Second argument can't be less than first")
    printRange.call(j, k, odd)
} else {
    var l = -k
    if (j > l) Fiber.abort("The second argument can't be less in absolute value than first")
    printBetween.call(j, l, odd)
}


      *FLOAT 64
      PRINT "Mersenne Primes:"
      FOR p% = 2 TO 23
        IF FNlucas_lehmer(p%) PRINT "M" ; p%
      NEXT
      END

      DEF FNlucas_lehmer(p%)
      LOCAL i%, mp, sn
      IF p% = 2 THEN = TRUE
      IF (p% AND 1) = 0 THEN = FALSE
      mp = 2^p% - 1
      sn = 4
      FOR i% = 3 TO p%
        sn = sn^2 - 2
        sn -= (mp * INT(sn / mp))
      NEXT
      = (sn = 0)


GET "libhdr"

LET M(n) = (1 << n) - 1

LET isMersennePrime(p) =
    p < 3 -> p = 2,
    VALOF {
        LET n = M(p)
        LET s = 4
        FOR i = 1 TO p-2 DO {
            muldiv(s, s, n) // ignore quotient; remainder is in result2
            s := result2 - 2
            s := s + (n & s < 0)
        }
        RESULTIS s = 0
    }

LET start() = VALOF {
    LET primes = #x28208A20A08A28AC // bitmask of primes upto 63

    writes("These Mersenne numbers are prime: ")
    FOR k = 0 TO 63 DO
        IF (primes & 1 << k) ~= 0 & isMersennePrime(k) THEN
            writef("M%d  ", k)

    wrch('*n')
    RESULTIS 0
}


  ( clk$:?t0:?now
  & ( time
    =   ( print
        =
          .   put
            $ ( str
              $ ( div$(!arg,1)
                  ","
                  (   div$(mod$(!arg*100,100),1):?arg
                    & !arg:<10
                    & 0
                  |
                  )
                  !arg
                  " "
                )
              )
        )
      & -1*!now+(clk$:?now):?SEC
      & print$!SEC
      & print$(!now+-1*!t0)
      & put$"s: "
    )
  & 3:?exponent
  &   whl
    ' ( !exponent:~>12000
      & (   !exponent^(!exponent^-1):!exponent^%
          & 4:?s
          & 2^!exponent+-1:?n
          & 0:?i
          &   whl
            ' ( 1+!i:?i
              & !exponent+-2:~<!i
              & mod$(!s^2+-2.!n):?s
              )
          & (   !s:0
              & !time
              & out$(str$(M !exponent " is PRIME!"))
            |
            )
        |
        )
      & 1+!exponent:?exponent
      )
  & done
  );


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 racket

(require racket/sandbox)

(define tests '([-2  2  1 "Normal"]
                [-2  2  0 "Zero increment"]
                [-2  2 -1 "Increments away from stop value"]
                [-2  2 10 "First increment is beyond stop value"]
                [2  -2  1 "Start more than stop: positive increment"]
                [2   2  1 "Start equal stop: positive increment"]
                [2   2 -1 "Start equal stop: negative increment"]
                [2   2  0 "Start equal stop: zero increment"]
                [0   0  0 "Start equal stop equal zero: zero increment"]))

(for ([test (in-list tests)])
  (match-define (list st ed inc desc) test)
  (printf "~a:\n  (in-range ~a ~a ~a) = ~a\n\n"
          desc st ed inc
          (with-handlers ([exn:fail:resource? (thunk* 'timeout)])
            (with-limits 1 #f
              (sequence->list (in-range st ed inc))))))


# Given sequence definitions
#   start  stop  inc.   Comment
for   -2,    2,    1, # Normal
      -2,    2,    0, # Zero increment
      -2,    2,   -1, # Increments away from stop value
      -2,    2,   10, # First increment is beyond stop value
       2,   -2,    1, # Start more than stop: positive increment
       2,    2,    1, # Start equal stop: positive increment
       2,    2,   -1, # Start equal stop: negative increment
       2,    2,    0, # Start equal stop: zero increment
       0,    0,    0, # Start equal stop equal zero: zero increment

# Additional "problematic" sequences
       1,  Inf,    3, # Endpoint literally at infinity
       0,    π,  τ/8, # Floating point numbers
     1.4,    *, -7.1  # Whatever

  -> $start, $stop, $inc {
    my $seq = flat ($start, *+$inc … $stop);
    printf "Start: %3s, Stop: %3s, Increment: %3s | ", $start, $stop.Str, $inc;
    # only show up to the first 15 elements of possibly infinite sequences
    put $seq[^15].grep: +*.defined
}

# For that matter the start and end values don't need to be numeric either. Both
# or either can be a function, list, or other object. Really anything that a
# "successor" function can be defined for and produces a value.
say "\nDemonstration of some other specialized sequence operator functionality:";
# Start with a list, iterate by multiplying the previous 3 terms together
# and end with a term defined by a function.
put 1, -.5, 2.sqrt, * × * × * … *.abs < 1e-2;

# Start with an array, iterate by rotating, end when 0 is in the last place.
say [0,1,2,3,4,5], *.rotate(-1).Array … !*.tail;

# Iterate strings backwards.
put 'xp' … 'xf';


/*REXX program demonstrates several versions of  DO  loops with  "unusual"  iterations. */
@.=;      @.1=  '  -2      2       1  '      /*"normal".                                */
          @.2=  '  -2      2       0  '      /*"normal",                zero  increment.*/
          @.3=  '  -2      2      -1  '      /*increases away from stop, neg  increment.*/
          @.4=  '  -2      2      10  '      /*1st increment > stop, positive increment.*/
          @.5=  '   2     -2       1  '      /*start > stop,         positive increment.*/
          @.6=  '   2      2       1  '      /*start equals stop,    positive increment.*/
          @.7=  '   2      2      -1  '      /*start equals stop,    negative increment.*/
          @.8=  '   2      2       0  '      /*start equals stop,       zero  increment.*/
          @.9=  '   0      0       0  '      /*start equals stop,       zero  increment.*/
zLim= 10                                     /*a limit to check for runaway (race) loop.*/
                                             /*a zero increment is not an error in REXX.*/
  do k=1  while  @.k\==''                    /*perform a  DO  loop with several ranges. */
  parse var   @.k    x  y  z  .              /*obtain the three values for a DO loop.   */
  say
  say center('start of performing DO loop number '   k   " with range: "  x y z,  79, '═')
  zz= 0
        do  j=x   to y   by z   until zz>=zLim           /* ◄───  perform the  DO  loop.*/
        say '   j ───►'  right(j, max(3, length(j) ) )   /*right justify J for alignment*/
        if z==0  then zz= zz + 1                         /*if zero inc, count happenings*/
        end   /*j*/

  if zz>=zLim  then say 'the DO loop for the '    k    " entry was terminated (runaway)."
  say center(' end  of performing DO loop number '   k   " with range: "  x y z,  79, '─')
  say
  end         /*k*/                              /*stick a fork in it,  we're all done. */


fcn lgen(a){
   ns,idx:=[a..*,2],2;
   vm.yield(ns.next());
   while(1){
      n:=ns.next();
      vm.yield(n);
      ns=ns.tweak(skipper.fp1(n,Ref(idx+=1)));  // tack on another filter
   }
}
fcn skipper(n,skp,cnt){ z:=cnt.inc(); if(z%skp==0) Void.Skip else n  }


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

int lucas_lehmer(unsigned long p)
{
  mpz_t V, mp, t;
  unsigned long k, tlim;
  int res;

  if (p == 2) return 1;
  if (!(p&1)) return 0;

  mpz_init_set_ui(t, p);
  if (!mpz_probab_prime_p(t, 25)) /* if p is composite, 2^p-1 is not prime */
    { mpz_clear(t); return 0; }

  if (p < 23)                     /* trust the PRP test for these values */
    { mpz_clear(t); return (p != 11); }

  mpz_init(mp);
  mpz_setbit(mp, p);
  mpz_sub_ui(mp, mp, 1);

  /* If p=3 mod 4 and p,2p+1 both prime, then 2p+1 | 2^p-1.  Cheap test. */
  if (p > 3 && p % 4 == 3) {
    mpz_mul_ui(t, t, 2);
    mpz_add_ui(t, t, 1);
    if (mpz_probab_prime_p(t,25) && mpz_divisible_p(mp, t))
      { mpz_clear(mp); mpz_clear(t); return 0; }
  }

  /* Do a little trial division first.  Saves quite a bit of time. */
  tlim = p/2;
  if (tlim > (ULONG_MAX/(2*p)))
    tlim = ULONG_MAX/(2*p);
  for (k = 1; k < tlim; k++) {
    unsigned long q = 2*p*k+1;
    /* factor must be 1 or 7 mod 8 and a prime */
    if ( (q%8==1 || q%8==7) &&
         q % 3 && q % 5 && q % 7 &&
         mpz_divisible_ui_p(mp, q) )
      { mpz_clear(mp); mpz_clear(t); return 0; }
  }

  mpz_init_set_ui(V, 4);
  for (k = 3; k <= p; k++) {
    mpz_mul(V, V, V);
    mpz_sub_ui(V, V, 2);
    /* mpz_mod(V, V, mp) but more efficiently done given mod 2^p-1 */
    if (mpz_sgn(V) < 0) mpz_add(V, V, mp);
    /* while (n > mp) { n = (n >> p) + (n & mp) } if (n==mp) n=0 */
    /* but in this case we can have at most one loop plus a carry */
    mpz_tdiv_r_2exp(t, V, p);
    mpz_tdiv_q_2exp(V, V, p);
    mpz_add(V, V, t);
    while (mpz_cmp(V, mp) >= 0) mpz_sub(V, V, mp);
  }
  res = !mpz_sgn(V);
  mpz_clear(t); mpz_clear(mp); mpz_clear(V);
  return res;
}

int main(int argc, char* argv[]) {
  unsigned long i, n = 43112609;
  if (argc >= 2) n = strtoul(argv[1], 0, 10);
  for (i = 1; i <= n; i++) {
    if (lucas_lehmer(i)) {
      printf("M%lu ", i);
      fflush(stdout);
    }
  }
  printf("\n");
  return 0;
}


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


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

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

fn main() {
    // ludic() is so quick we just call it repeatedly
    println("First 25: ${ludic(25, -1)}")
    println("Numner of ludics below 1000: ${ludic(-1, 1000).len}")
    println("ludic 2000 to 2005: ${ludic(2005, -1)[1999..]}")

    print("Tripples below 250:")
    x := ludic(-1, 250)
    for i, v in x[..x.len-2] {
        if has(x[i+1..], v+2) && has(x[i+2..], v+6) {
            print(", ($v ${v+2} ${v+6})")
        }
    }
    println('')
}


$ include "seed7_05.s7i";

const proc: testLoop (in integer: start, in integer: stop, in integer: incr, in string: comment) is func
  local
    const integer: limit is 10;
    var integer: number is 0;
    var integer: count is 0;
  begin
    writeln(comment);
    write("Range(" <& start <& ", " <& stop <& ", " <& incr <& ") -> [ ");
    block
      for number range start to stop step incr do
        write(number <& " ");
        incr(count);
        if count >= limit then
          raise RANGE_ERROR;
        end if;
      end for;
    exception
      catch RANGE_ERROR: noop;
    end block;
    writeln("]");
    writeln;
  end func;

const proc: main is func
  begin
    testLoop(-2,  2,  1, "Normal");
    testLoop(-2,  2,  0, "Zero increment");
    testLoop(-2,  2, -1, "Increments away from stop value");
    testLoop(-2,  2, 10, "First increment is beyond stop value");
    testLoop( 2, -2,  1, "Start more than stop: positive increment");
    testLoop( 2,  2,  1, "Start equal stop: positive increment");
    testLoop( 2,  2, -1, "Start equal stop: negative increment");
    testLoop( 2,  2,  0, "Start equal stop: zero increment");
    testLoop( 0,  0,  0, "Start equal stop equal zero: zero increment");
  end func;


startExpr to:stopExpr by:incExpr do:[..]


static void example(int start, int stop, int increment, string comment) {
  const int MAX_ITER = 9;
  int iteration = 0;
  stdout.printf("%-50s", comment);
  for (int i = start; i <= stop; i += increment) {
    stdout.printf("%3d ", i);
    if (++iteration > MAX_ITER) break;
  }
  stdout.printf("\n");
}

void main () {
  example(-2, 2, 1, "Normal");
  example(-2, 2, 0, "Zero increment");
  example(-2, 2, -1, "Increments away from stop value");
  example(-2, 2, 10, "First increment is beyond stop value");
  example(2, -2, 1, "Start more than stop: positive increment");
  example(2, 2, 1, "Start equals stop: positive increment");
  example(2, 2, -1, "Start equals stop: negative increment");
  example(2, 2, 0, "Start equals stop: zero increment");
  example(0, 0, 0, "Start equals stop equal zero: zero increment");
}


using System;
using System.Collections.Generic;
using System.Numerics;
using System.Threading.Tasks;

namespace LucasLehmerTestForRosettaCode
{
    public class LucasLehmerTest
    {
        static BigInteger ZERO = new BigInteger(0);
        static BigInteger ONE = new BigInteger(1);
        static BigInteger TWO = new BigInteger(2);
        static BigInteger FOUR = new BigInteger(4);

        private static bool isMersennePrime(int p)
        {
            if (p % 2 == 0) return (p == 2);
            else {
                for (int i = 3; i <= (int)Math.Sqrt(p); i += 2)
                    if (p % i == 0) return false; //not prime
                BigInteger m_p = BigInteger.Pow(TWO, p) - ONE;
                BigInteger s = FOUR;
                for (int i = 3; i <= p; i++)
                    s = (s * s - TWO) % m_p;
                return s == ZERO;
            }
        }

        public static int[] GetMersennePrimeNumbers(int upTo)
        {
            List<int> response = new List<int>();
            Parallel.For(2, upTo + 1, i => {
                if (isMersennePrime(i)) response.Add(i);
            });
            response.Sort();
            return response.ToArray();
        }

        static void Main(string[] args)
        {
            int[] mersennePrimes = LucasLehmerTest.GetMersennePrimeNumbers(11213);
            foreach (int mp in mersennePrimes)
                Console.Write("M" + mp+" ");
            Console.ReadLine();
        }
    }
}


import "/fmt" for Fmt

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

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

System.print("First 25: %(ludic.call(25, -1))")
System.print("Number of Ludics below 1000: %(ludic.call(-1, 1000).count)")
System.print("Ludics 2000 to 2005: %(ludic.call(2005, -1)[1999..-1])")
System.print("Triplets below 250:")
var x = ludic.call(-1, 250)
var i = 0
var triples = []
for (v in x.take(x.count-2)) {
    if (has.call(x[i+1..-1], v+2) && has.call(x[i+2..-1], v+6)) {
        triples.add([v, v+2, v+6])
    }
    i = i + 1
}
System.print(triples)


Public Sub LoopsWrongRanges()
    Call Example(-2, 2, 1, "Normal")
    Call Example(-2, 2, 0, "Zero increment")
    Call Example(-2, 2, -1, "Increments away from stop value")
    Call Example(-2, 2, 10, "First increment is beyond stop value")
    Call Example(2, -2, 1, "Start more than stop: positive increment")
    Call Example(2, 2, 1, "Start equal stop: positive increment")
    Call Example(2, 2, -1, "Start equal stop: negative increment")
    Call Example(2, 2, 0, "Start equal stop: zero increment")
    Call Example(0, 0, 0, "Start equal stop equal zero: zero increment")
End Sub
Private Sub Example(start As Integer, stop_ As Integer, by As Integer, comment As String)
    Dim i As Integer
    Dim c As Integer
    Const limit = 10
    c = 0
    Debug.Print start; " "; stop_; " "; by; " | ";
    For i = start To stop_ Step by
        Debug.Print i & ",";
        c = c + 1
        If c > limit Then Exit For
    Next i
    Debug.Print
    Debug.Print comment & vbCrLf
End Sub


Module Program
    Sub Main()
        Example(-2, 2, 1, "Normal")
        Example(-2, 2, 0, "Zero increment")
        Example(-2, 2, -1, "Increments away from stop value")
        Example(-2, 2, 10, "First increment is beyond stop value")
        Example(2, -2, 1, "Start more than stop: positive increment")
        Example(2, 2, 1, "Start equal stop: positive increment")
        Example(2, 2, -1, "Start equal stop: negative increment")
        Example(2, 2, 0, "Start equal stop: zero increment")
        Example(0, 0, 0, "Start equal stop equal zero: zero increment")
    End Sub

    ' Stop is a keyword and must be escaped using brackets.
    Iterator Function Range(start As Integer, [stop] As Integer, increment As Integer) As IEnumerable(Of Integer)
        For i = start To [stop] Step increment
            Yield i
        Next
    End Function

    Sub Example(start As Integer, [stop] As Integer, increment As Integer, comment As String)
        ' Add a space, pad to length 50 with hyphens, and add another space.
        Console.Write((comment & " ").PadRight(50, "-"c) & " ")

        Const MAX_ITER = 9

        Dim iteration = 0
        ' The For Each loop enumerates the IEnumerable.
        For Each i In Range(start, [stop], increment)
            Console.Write("{0,2} ", i)

            iteration += 1
            If iteration > MAX_ITER Then Exit For
        Next

        Console.WriteLine()
    End Sub
End Module


#include <iostream>
#include <gmpxx.h>

static bool is_mersenne_prime(mpz_class p)
{
        if( 2 == p )
                return true;
        else
        {
                mpz_class s(4);
                mpz_class div( (mpz_class(1) << p.get_ui()) - 1 );
                for( mpz_class i(3);  i <= p;  ++i )
                {
                        s =  (s * s - mpz_class(2)) % div ;
                }

                return ( s == mpz_class(0) );
        }
}

int main()
{
        mpz_class maxcount(45);
        mpz_class found(0);
        mpz_class check(0);
        for( mpz_nextprime(check.get_mpz_t(), check.get_mpz_t());
             found < maxcount;
             mpz_nextprime(check.get_mpz_t(), check.get_mpz_t()))
        {
                //std::cout << "P" << check << " " << std::flush;
                if( is_mersenne_prime(check) )
                {
                        ++found;
                        std::cout << "M" << check << " " << std::flush;
                }
        }
}


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
}


struct Seq {
    start int
    stop int
    incr int
    comment          string
}

const examples = [
    Seq{-2, 2, 1, "Normal"},
    Seq{-2, 2, 0, "Zero increment"},
    Seq{-2, 2, -1, "Increments away from stop value"},
    Seq{-2, 2, 10, "First increment is beyond stop value"},
    Seq{2, -2, 1, "Start more than stop: positive increment"},
    Seq{2, 2, 1, "Start equal stop: positive increment"},
    Seq{2, 2, -1, "Start equal stop: negative increment"},
    Seq{2, 2, 0, "Start equal stop: zero increment"},
    Seq{0, 0, 0, "Start equal stop equal zero: zero increment"},
]

fn sequence(s Seq, limit int) []int {
    mut seq := []int{}
    for i, c := s.start, 0; i <= s.stop && c < limit; i, c = i+s.incr, c+1 {
        seq << i
    }
    return seq
}

fn main() {
    limit := 10
    for ex in examples {
        println(ex.comment)
        print("Range($ex.start, $ex.stop, $ex.incr) -> ")
        println(sequence(ex, limit))
        println('')
    }
}


import "/fmt" for Fmt

var loop = Fn.new { |start, stop, inc|
    System.write("%(Fmt.v("dm", 3, [start, stop, inc], 0, " ", "[]")) -> ")
    var count = 0
    var limit = 10
    var i = start
    while (i <= stop) {
        System.write("%(i) ")
        count = count + 1
        if (count == limit) break
        i = i + inc
    }
    System.print()
}

var tests = [
    [-2, 2, 1], [-2, 2, 0], [-2, 2, -1], [-2, 2, 10], [2, -2, 1], [2, 2, 1], [2, 2, -1], [2, 2, 0], [0, 0, 0]
]
for (test in tests) loop.call(test[0], test[1], test[2])


data -2,2,1,"Normal",-2,2,0,"Zero increment",-2,2,-1,"Increments away from stop value"
data -2,2,10,"First increment is beyond stop value",2,-2,1,"Start more than stop: positive increment"
data 2,2,1,"Start equal stop: positive increment",2,2,-1,"Start equal stop: negative increment"
data 2,2,0,"Start equal stop: zero increment",0,0,0,"Start equal stop equal zero: zero increment"

for i = 1 to 9
    contar = 0
    read start, fin, inc, cmt$
    print cmt$
    print "  Bucle de ", start, " a ", fin, " en incrementos de ", inc
    for vr = start to fin step inc
        print "        Indice del bucle = ", vr
        contar = contar + 1
        if contar = 10 then
            print "        Saliendo de un bucle infinito"
            break
        endif
    next vr
    print "  Bucle terminado\n\n"
next i
end


(defn prime? [i]
  (cond (< i 4)           (>= i 2)
        (zero? (rem i 2)) false
  :else (not-any? #(zero? (rem i %)) (range 3 (inc (Math/sqrt i))))))))

(defn mersenne? [p] (or (= p 2)
  (let [mp   (dec (bit-shift-left 1 p))]
    (loop [n 3 s 4]
      (if (> n p)
        (zero? s)
        (recur (inc n) (rem (- (* s s) 2) mp)))))))

(filter mersenne? (filter prime? (iterate inc 1)))


sorenson = require('sieve').primes  # Sorenson's extensible sieve from task: Extensible Prime Number Generator

# Test if 2^n-1 is a Mersenne prime.
# assumes that the argument p is prime.
#
isMersennePrime = (p) ->
    if p is 2 then yes
    else
        n = (1n << BigInt p) - 1n
        s = 4n
        s = (s*s - 2n) % n for _ in [1..p-2]
        s is 0n

primes = sorenson()
mersennes = []
while (p = primes.next().value) < 3000
    if isMersennePrime(p)
        mersennes.push p

console.log "Some Mersenne primes: #{"M" + String p for p in mersennes}"


// zero increment (ie infnite loop) throws an error
// if stop is "*", the loop is has no end (ie infinite)
// stop is included unless step steps skips it
// if start > stop is a dead loop
// ranges ([a..b,c]) are lazy lists
fcn looper([(start,stop,increment)]){
   print(" %3s  %3s\t%2d --> ".fmt(start,stop,increment));
   try{ foreach n in ([start..stop,increment]){ print(n," ") } }
   catch{ print(__exception) }
   println();
}
println("start stop  increment");
T( T(-2,2,1),T(-2,2,0),T(-2,2,-1),T(-2,2,10),T( 2,-2,1),
   T( 2,2,1),T( 2,2,-1),T( 2,2,0),T( 0,0,0),
   T(0.0, (0.0).pi, 0.7853981633974483), T("a","e",1), T("e","a",1) )
.apply2(looper);  // apply2 is apply (map) without saving results


(defun or-f (&optional a b) (or a b));necessary for reduce, as 'or' is implemented as a macro

(defun prime-p (n)
  (cond ((< n  4) (>= n 2))
        ((zerop (rem n 2)) nil)
        (t (not (reduce #'or-f (mapcar (lambda (x) (zerop (rem n x))) (loop for i from 3 to (sqrt n) collect i)))))))

(defun mersenne-p (p)
  (or (= p 2)
      (let ((mp (- 1 (expt 2 p))))
        (do ((n 3) (s 4))
          ((> n p) (zerop s))
          (incf n)
          (setf s (rem (- (* s s) 2) mp))))))

(princ (remove-if-not #'mersenne-p (remove-if-not #'prime-p (loop for i to 5000 collect i))))