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

public class Program
{
    public static void Main()
    {
        Console.WriteLine("First 25 ludic numbers:");
        Console.WriteLine(string.Join(", ", LudicNumbers(150).Take(25)));
        Console.WriteLine();

        Console.WriteLine($"There are {LudicNumbers(1001).Count()} ludic numbers below 1000");
        Console.WriteLine();

        foreach (var ludic in LudicNumbers(22000).Skip(1999).Take(6)
                .Select((n, i) => $"#{i+2000} = {n}")) {
            Console.WriteLine(ludic);
        }
        Console.WriteLine();

        Console.WriteLine("Triplets below 250:");
        var queue = new Queue<int>(5);
        foreach (int x in LudicNumbers(255)) {
            if (queue.Count == 5) queue.Dequeue();
            queue.Enqueue(x);
            if (x - 6 < 250 && queue.Contains(x - 6) && queue.Contains(x - 4)) {
                Console.WriteLine($"{x-6}, {x-4}, {x}");
            }
        }
    }

    public static IEnumerable<int> LudicNumbers(int limit) {
        yield return 1;
        //Like a linked list, but with value types.
        //Create 2 extra entries at the start to avoid ugly index calculations
        //and another at the end to avoid checking for index-out-of-bounds.
        Entry[] values = Enumerable.Range(0, limit + 1).Select(n => new Entry(n)).ToArray();
        for (int i = 2; i < limit; i = values[i].Next) {
            yield return values[i].N;
            int start = i;
            while (start < limit) {
                Unlink(values, start);
                for (int step = 0; step < i && start < limit; step++)
                    start = values[start].Next;
            }
        }
    }

    static void Unlink(Entry[] values, int index) {
        values[values[index].Prev].Next = values[index].Next;
        values[values[index].Next].Prev = values[index].Prev;
    }

}

struct Entry
{
    public Entry(int n) : this() {
        N = n;
        Prev = n - 1;
        Next = n + 1;
    }

    public int N { get; }
    public int Prev { get; set; }
    public int Next { get; set; }
}


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

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

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

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

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

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

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

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

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

    vector<int> _list;
};

int main( int argc, char* argv[] )
{
    ludic l;
    l.ludicList();
    cout << "first 25 ludic numbers:" << "\n";
    l.show( 0, 25 );
    cout << "\n\nThere are " << l.count( 1000 ) << " ludic numbers <= 1000" << "\n";
    cout << "\n2000 to 2005'th ludic numbers:" << "\n";
    l.show( 1999, 2005 );
    cout << "\n\nall triplets of ludic numbers < 250:" << "\n";
    l.findTriplets( 250 );
    cout << "\n\n";
    return system( "pause" );
}


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

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

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

(defn ludic? [n]  (= (first (filter (partial <= n) ludic)) n))

(print "First 25: ")
(println (take 25 ludic))
(print "Count below 1000: ")
(println (count (take-while (partial > 1000) ludic)))
(print "2000th through 2005th: ")
(println (map (partial nth ludic) (range 1999 2005)))
(print "Triplets < 250: ")
(println (filter (partial every? ludic?)
         (for [i (range 250)] (list i (+ i 2) (+ i 6)))))


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

(defun main ()
  (format t "First 25 ludic numbers:~%")
  (format t "~{~D~^ ~}~%" (ludic-numbers 100 25))
  (terpri)
  (format t "How many ludic numbers <= 1000?~%")
  (format t "~D~%" (length (ludic-numbers 1000)))
  (terpri)
  (let ((numbers (ludic-numbers 30000 2005)))
    (format t "~{#~D: ~D~%~}"
            (mapcan #'list '(2000 2001 2002 2003 2004 2005) (nthcdr 1999 numbers))))
  (terpri)
  (loop with numbers = (ludic-numbers 250)
          initially (format t "Triplets:~%")
        for x in numbers
        when (and (find (+ x 2) numbers)
                  (find (+ x 6) numbers))
          do (format t "~3D ~3D ~3D~%" x (+ x 2) (+ x 6))))


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

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

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

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

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

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

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

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


class
	LUDIC_NUMBERS

create
	make

feature

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

	ludic_numbers: ARRAY [INTEGER]

feature {NONE}

	initial: ARRAY [INTEGER]

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

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

end


defmodule Ludic do
  def numbers(n \\ 100000) do
    [h|t] = Enum.to_list(1..n)
    numbers(t, [h])
  end

  defp numbers(list, nums) when length(list) < hd(list), do: Enum.reverse(nums, list)
  defp numbers([h|_]=list, nums) do
    Enum.drop_every(list, h) |> numbers([h | nums])
  end

  def task do
    IO.puts "First 25 : #{inspect numbers(200) |> Enum.take(25)}"
    IO.puts "Below 1000: #{length(numbers(1000))}"
    tuple = numbers(25000) |> List.to_tuple
    IO.puts "2000..2005th: #{ inspect for i <- 1999..2004, do: elem(tuple, i) }"
    ludic = numbers(250)
    triple = for x <- ludic, x+2 in ludic, x+6 in ludic, do: [x, x+2, x+6]
    IO.puts "Triples below 250: #{inspect triple, char_lists: :as_lists}"
  end
end

Ludic.task


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

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

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

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

MAIN: ludic-demo


program ludic_numbers
  implicit none

  integer, parameter :: nmax = 25000
  logical :: ludic(nmax) = .true.
  integer :: i, j, n

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

  write(*, "(a)", advance = "no") "First 25 Ludic numbers: "
  n = 0
  do i = 1, nmax
    if(ludic(i)) then
      write(*, "(i0, 1x)", advance = "no") i
      n = n + 1
    end if
    if(n == 25) exit
  end do

  write(*, "(/, a)", advance = "no") "Ludic numbers below 1000: "
  write(*, "(i0)") count(ludic(:999))

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

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

end program


' FB 1.05.0 Win64

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

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

  Do
     k += 1

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

     count2 = 0
     j = k + 1

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

End Sub

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

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

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

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

Print "Press any key to quit"
Sleep


package main

import "fmt"

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

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

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

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


import Data.List (unfoldr, genericSplitAt)

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

main :: IO ()
main = do
  print $ take 25 ludic
  (print . length) $ takeWhile (<= 1000) ludic
  print $ take 6 $ drop 1999 ludic
-- haven't done triplets task yet


global num, cascade, sieve, nfilter

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

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

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


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

public class Ludic{
	public static List<Integer> ludicUpTo(int n){
		List<Integer> ludics = new ArrayList<Integer>(n);
		for(int i = 1; i <= n; i++){   //fill the initial list
			ludics.add(i);
		}

		//start at index 1 because the first ludic number is 1 and we don't remove anything for it
		for(int cursor = 1; cursor < ludics.size(); cursor++){
			int thisLudic = ludics.get(cursor); //the first item in the list is a ludic number
			int removeCursor = cursor + thisLudic; //start removing that many items later
			while(removeCursor < ludics.size()){
				ludics.remove(removeCursor);		     //remove the next item
				removeCursor = removeCursor + thisLudic - 1; //move the removal cursor up as many spaces as we need to
									     //then back one to make up for the item we just removed
			}
		}
		return ludics;
	}

	public static List<List<Integer>> getTriplets(List<Integer> ludics){
		List<List<Integer>> triplets = new ArrayList<List<Integer>>();
		for(int i = 0; i < ludics.size() - 2; i++){ //only need to check up to the third to last item
			int thisLudic = ludics.get(i);
			if(ludics.contains(thisLudic + 2) && ludics.contains(thisLudic + 6)){
				List<Integer> triplet = new ArrayList<Integer>(3);
				triplet.add(thisLudic);
				triplet.add(thisLudic + 2);
				triplet.add(thisLudic + 6);
				triplets.add(triplet);
			}
		}
		return triplets;
	}

	public static void main(String[] srgs){
		System.out.println("First 25 Ludics: " + ludicUpTo(110));				//110 will get us 25 numbers
		System.out.println("Ludics up to 1000: " + ludicUpTo(1000).size());
		System.out.println("2000th - 2005th Ludics: " + ludicUpTo(22000).subList(1999, 2005));  //22000 will get us 2005 numbers
		System.out.println("Triplets up to 250: " + getTriplets(ludicUpTo(250)));
	}
}


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

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

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

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

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

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

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

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

console.log('\nTriplets smaller than 250:');
ludicResult.forEach(e => {
  if (e + 6 < 250 && ludicResult.indexOf(e + 2) > 0 && ludicResult.indexOf(e + 6) > 0) {
    console.log([e, e + 2, e + 6].join(', '));
  }
});


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

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

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

# Output: an array of the ludic numbers less than .
def ludic_primes:
  . as $n
  | def l:
      . as $k
      | [ludic(10*$k)] as $a
      | if $a[-1] >= $n then $a | map(select(. < $n))
        else (10*$k) | l
        end;
   l;

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

"First 25 ludic primes:", (25|first_ludic_primes),
"\nThere are \(1000|ludic_primes|length) ludic numbers <= 1000",
( "The \n2000th to 2005th ludic primes are:",
 (2005|first_ludic_primes)[2000:]),
( [250 | triplets]
  | "\nThere are \(length) triplets less than 250:",
    .[] )


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

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

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

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

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

n = 250
println()
println("Show all triplets of ludic numbers < ", n)
for i = 1:n-7
    slud[i] || continue
    j = i+2
    slud[j] || continue
    k = i+6
    slud[k] || continue
    println("    ", i, ", ", j, ", ", k)
end


// version 1.0.6

/* Rather than remove elements from a MutableList which would be a relatively expensive operation
   we instead use two arrays:

   1. An array of the Ludic numbers to be returned.
   2. A 'working' array of a suitable size whose elements are set to 0 to denote removal. */

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

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

    val count = lu.count { it <= 1000 }
    println("\n\nThere are $count Ludic numbers <= 1000" )

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

    println("\n\nThe Ludic triplets below 250 are : ")
    var k: Int = 0
    var ldc: Int
    var b: Boolean
    for (i in 0 .. 247) {
        ldc = lu[i]
        if (ldc >= 244) break
        b = false
        for (j in i + 1 .. 248) {
             if (lu[j] == ldc + 2) {
                 b = true
                 k = j
                 break
             }
             else if (lu[j] > ldc + 2) break
        }
        if (!b) continue
        for (j in k + 1 .. 249) {
            if (lu[j] == ldc + 6) {
                println("($ldc, ${ldc + 2}, ${ldc + 6})")
                break
            }
            else if (lu[j] > ldc + 6) break
        }
    }
}


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

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

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

-- Main procedure
local first25, under1k, inRange, tripList, triplets = {}, 0, {}, {}, {}
for k, v in pairs(ludics(30000)) do
    if k <= 25 then table.insert(first25, v) end
    if v <= 1000 then under1k = under1k + 1 end
    if k >= 2000 and k <= 2005 then table.insert(inRange, v) end
    if v < 250 then table.insert(tripList, v) end
end
for _, x in pairs(tripList) do
    if foundIn(tripList, x + 2) and foundIn(tripList, x + 6) then
        table.insert(triplets, "\n{" .. x .. "," .. x+2 .. "," .. x+6 .. "}")
    end
end
show("First 25:", first25)
print(under1k .. " are less than or equal to 1000\n")
show("2000th to 2005th:", inRange)
show("Triplets:", triplets)


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

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


import strutils

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

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

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

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

when isMainModule:

  let ludicArray = initLudicArray[2005]()

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

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

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

  echo "\nThe triplets of ludic numbers less than 250 are:"
  var line = ""
  for i, n in ludicArray:
    if n >= 244:
      echo line
      break
    if ludicArray.isLudic(n + 2, i + 1) and ludicArray.isLudic(n + 6, i + 2):
      line.addSep(", ")
      line.add "($1, $2, $3)".format(n, n + 2, n + 6)


use Collection.Generic;

class Ludic  {
  function : Main(args : String[]) ~ Nil {
    ludics := LudicUpTo(110);
    Show("First 25 Ludics: ", ludics, 0, ludics->Size());
    System.IO.Console->Print("Ludics up to 1000: ")->PrintLine(LudicUpTo(1000)->Size());
    ludics := LudicUpTo(22000);
    Show("2000th - 2005th Ludics: ", ludics, 1999, 2005);
    Show("Triplets up to 250: ", GetTriplets(LudicUpTo(250)));
  }

  function : LudicUpTo(n : Int) ~ CompareVector<IntHolder> {
    ludics := CompareVector->New()<IntHolder>;
    for(i := 1; i <= n; i++;){
      ludics->AddBack(i);
    };

    for(cursor := 1; cursor < ludics->Size(); cursor++;) {
      thisLudic := ludics->Get(cursor);
      removeCursor := cursor + thisLudic;
      while(removeCursor < ludics->Size()){
        ludics->Remove(removeCursor);
        removeCursor := removeCursor + thisLudic - 1;
      };
    };

    return ludics;
  }

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

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

    return triplets;
  }

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

  function : Show(title : String, triplets : Vector<CompareVector<IntHolder> >) ~ Nil {
    title->PrintLine();
    each(i : triplets) {
      triplet := triplets->Get(i);
      Show("\t", triplet, 0, triplet->Size());
    };
  }
}


-V NoValue = 0

F initLuckyNumbers(nelems, evenlucky, limit = -1)
   [Int] result
   L(i) 0 .< nelems
      V k = i
      L(j) (result.len - 1 .< 0).step(-1)
         k = k * result[j] I/ (result[j] - 1)
      V n = 2 * k + 1 + evenlucky
      I limit != -1 & n > limit
         L.break
      result.append(n)
   R result

F name(evenlucky)
   R [‘Lucky’, ‘Even lucky’][evenlucky]

F printSingle(j, evenlucky)
   V luckySeq = initLuckyNumbers(j, evenlucky)
   print(name(evenlucky)‘ number at index ’j‘ is ’luckySeq[j - 1])

F printRange(j, k, evenlucky)
   V luckySeq = initLuckyNumbers(k, evenlucky)
   print(name(evenlucky)‘ numbers at indexes ’j‘ to ’k‘ are: ’, end' ‘’)
   L(idx) j - 1 .< k
      I idx != j - 1
         print(‘, ’, end' ‘’)
      print(luckySeq[idx], end' ‘’)
   print()

F printInRange(j, k, evenlucky)
   V luckySeq = initLuckyNumbers(k, evenlucky, k)
   print(name(evenlucky)‘ numbers between ’j‘ to ’k‘ are: ’, end' ‘’)
   V first = 1B
   L(val) luckySeq
      I val > j
         I first
            first = 0B
         E
            print(‘, ’, end' ‘’)
         print(val, end' ‘’)
   print()

F process_args(args)
   assert(args.len C 1..3, ‘Wrong number of arguments’)

   // First argument: "j" value.
   V j = Int(args[0])

   V k = NoValue
   // Second argument: "k" value or a comma.
   I args.len > 1
      I args[1] == ‘,’
         // Must be followed by the kind of lucky number.
         assert(args.len == 3, ‘Missing kind argument’)
      E
         k = Int(args[1])
         assert(k != 0, ‘Expected a non null number’)

   V evenlucky = 0
   // Third argument: number kind.
   I args.len == 3
      V kind = args[2].lowercase()
      assert(kind C (‘lucky’, ‘evenlucky’), ‘Wrong kind’)
      I kind == ‘evenlucky’
         evenlucky = 1

   I k == NoValue
      // Print jth value.
      printSingle(j, evenlucky)
   E I k > 0
      // Print jth to kth values.
      printRange(j, k, evenlucky)
   E
      // Print values in range j..(-k).
      printInRange(j, -k, evenlucky)

:start:
I 1B
   L(args) [‘1 20’, ‘1 20 evenlucky’, ‘6000 -6100’, ‘6000 -6100 evenlucky’, ‘10000’, ‘10000 , lucky’, ‘10000 , evenlucky’]
      print(‘Command line arguments: ’args)
      process_args(args.split(‘ ’))
      print()
E
   process_args(:argv[1..])


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

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

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

   250 loop: i [
      l include(i) ifFalse: [ continue ]
      l include(i 2 +) ifFalse: [ continue ]
      l include(i 6 +) ifFalse: [ continue ]
      i print ", " print i 2 + print ", " print i 6 + println
      ] ;


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

{
\\ Required tests:
my(Vr,L=List(),k=0,maxn=25000);
Vr=ludic(maxn);
print("The first 25 Ludic numbers: ");
for(i=1,maxn, if(Vr[i]==1, k++; print1(i," "); if(k==25, break)));
print("");print("");
k=0;
for(i=1,999, if(Vr[i]==1, k++));
print("Ludic numbers below 1000: ",k);
print("");
k=0;
print("Ludic numbers 2000 to 2005: ");
for(i=1,maxn, if(Vr[i]==1, k++; if(k>=2000&&k<=2005, listput(L,i)); if(k>2005, break)));
for(i=1,6, print1(L[i]," "));
print(""); print("");
print("Ludic Triplets below 250: ");
for(i=1,250, if(Vr[i]&&Vr[i+2]&&Vr[i+6], print1("(",i," ",i+2," ",i+6,") ")));
}


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

#define LUCKY_SIZE 60000
int luckyOdd[LUCKY_SIZE];
int luckyEven[LUCKY_SIZE];

void compactLucky(int luckyArray[]) {
    int i, j, k;

    for (i = 0; i < LUCKY_SIZE; i++) {
        if (luckyArray[i] == 0) {
            j = i;
            break;
        }
    }

    for (j = i + 1; j < LUCKY_SIZE; j++) {
        if (luckyArray[j] > 0) {
            luckyArray[i++] = luckyArray[j];
        }
    }

    for (; i < LUCKY_SIZE; i++) {
        luckyArray[i] = 0;
    }
}

void initialize() {
    int i, j;

    // unfiltered
    for (i = 0; i < LUCKY_SIZE; i++) {
        luckyEven[i] = 2 * i + 2;
        luckyOdd[i] = 2 * i + 1;
    }

    // odd filter
    for (i = 1; i < LUCKY_SIZE; i++) {
        if (luckyOdd[i] > 0) {
            for (j = luckyOdd[i] - 1; j < LUCKY_SIZE; j += luckyOdd[i]) {
                luckyOdd[j] = 0;
            }
            compactLucky(luckyOdd);
        }
    }

    // even filter
    for (i = 1; i < LUCKY_SIZE; i++) {
        if (luckyEven[i] > 0) {
            for (j = luckyEven[i] - 1; j < LUCKY_SIZE; j += luckyEven[i]) {
                luckyEven[j] = 0;
            }
            compactLucky(luckyEven);
        }
    }
}

void printBetween(size_t j, size_t k, bool even) {
    int i;

    if (even) {
        if (luckyEven[j] == 0 || luckyEven[k] == 0) {
            fprintf(stderr, "At least one argument is too large\n");
            exit(EXIT_FAILURE);
        }
        printf("Lucky even numbers between %d and %d are:", j, k);
        for (i = 0; luckyEven[i] != 0; i++) {
            if (luckyEven[i] > k) {
                break;
            }
            if (luckyEven[i] > j) {
                printf(" %d", luckyEven[i]);
            }
        }
    } else {
        if (luckyOdd[j] == 0 || luckyOdd[k] == 0) {
            fprintf(stderr, "At least one argument is too large\n");
            exit(EXIT_FAILURE);
        }
        printf("Lucky numbers between %d and %d are:", j, k);
        for (i = 0; luckyOdd[i] != 0; i++) {
            if (luckyOdd[i] > k) {
                break;
            }
            if (luckyOdd[i] > j) {
                printf(" %d", luckyOdd[i]);
            }
        }
    }
    printf("\n");
}

void printRange(size_t j, size_t k, bool even) {
    int i;

    if (even) {
        if (luckyEven[k] == 0) {
            fprintf(stderr, "The argument is too large\n");
            exit(EXIT_FAILURE);
        }
        printf("Lucky even numbers %d to %d are:", j, k);
        for (i = j - 1; i < k; i++) {
            printf(" %d", luckyEven[i]);
        }
    } else {
        if (luckyOdd[k] == 0) {
            fprintf(stderr, "The argument is too large\n");
            exit(EXIT_FAILURE);
        }
        printf("Lucky numbers %d to %d are:", j, k);
        for (i = j - 1; i < k; i++) {
            printf(" %d", luckyOdd[i]);
        }
    }
    printf("\n");
}

void printSingle(size_t j, bool even) {
    if (even) {
        if (luckyEven[j] == 0) {
            fprintf(stderr, "The argument is too large\n");
            exit(EXIT_FAILURE);
        }
        printf("Lucky even number %d=%d\n", j, luckyEven[j - 1]);
    } else {
        if (luckyOdd[j] == 0) {
            fprintf(stderr, "The argument is too large\n");
            exit(EXIT_FAILURE);
        }
        printf("Lucky number %d=%d\n", j, luckyOdd[j - 1]);
    }
}

void help() {
    printf("./lucky j [k] [--lucky|--evenLucky]\n");
    printf("\n");
    printf("       argument(s)        |  what is displayed\n");
    printf("==============================================\n");
    printf("-j=m                      |  mth lucky number\n");
    printf("-j=m  --lucky             |  mth lucky number\n");
    printf("-j=m  --evenLucky         |  mth even lucky number\n");
    printf("-j=m  -k=n                |  mth through nth (inclusive) lucky numbers\n");
    printf("-j=m  -k=n  --lucky       |  mth through nth (inclusive) lucky numbers\n");
    printf("-j=m  -k=n  --evenLucky   |  mth through nth (inclusive) even lucky numbers\n");
    printf("-j=m  -k=-n               |  all lucky numbers in the range [m, n]\n");
    printf("-j=m  -k=-n  --lucky      |  all lucky numbers in the range [m, n]\n");
    printf("-j=m  -k=-n  --evenLucky  |  all even lucky numbers in the range [m, n]\n");
}

void process(int argc, char *argv[]) {
    bool evenLucky = false;
    int j = 0;
    int k = 0;

    bool good = false;
    int i;

    for (i = 1; i < argc; ++i) {
        if ('-' == argv[i][0]) {
            if ('-' == argv[i][1]) {
                // long args
                if (0 == strcmp("--lucky", argv[i])) {
                    evenLucky = false;
                } else if (0 == strcmp("--evenLucky", argv[i])) {
                    evenLucky = true;
                } else {
                    fprintf(stderr, "Unknown long argument: [%s]\n", argv[i]);
                    exit(EXIT_FAILURE);
                }
            } else {
                // short args
                if ('j' == argv[i][1] && '=' == argv[i][2] && argv[i][3] != 0) {
                    good = true;
                    j = atoi(&argv[i][3]);
                } else if ('k' == argv[i][1] && '=' == argv[i][2]) {
                    k = atoi(&argv[i][3]);
                } else {
                    fprintf(stderr, "Unknown short argument: [%s]\n", argv[i]);
                    exit(EXIT_FAILURE);
                }
            }
        } else {
            fprintf(stderr, "Unknown argument: [%s]\n", argv[i]);
            exit(EXIT_FAILURE);
        }
    }

    if (!good) {
        help();
        exit(EXIT_FAILURE);
    }

    if (k > 0) {
        printRange(j, k, evenLucky);
    } else if (k < 0) {
        printBetween(j, -k, evenLucky);
    } else {
        printSingle(j, evenLucky);
    }
}

void test() {
    printRange(1, 20, false);
    printRange(1, 20, true);

    printBetween(6000, 6100, false);
    printBetween(6000, 6100, true);

    printSingle(10000, false);
    printSingle(10000, true);
}

int main(int argc, char *argv[]) {
    initialize();

    //test();

    if (argc < 2) {
        help();
        return 1;
    }
    process(argc, argv);

    return 0;
}


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

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

  tDelta = record
             dNum,
             dCnt : LongInt;
           end;

  tpDelta = ^tDelta;
  tLudicList = array of tDelta;

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

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

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

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

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

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

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

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

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

end;
var
  LudicList : tLudicList;
BEGIN
  setlength(LudicList,maxLudicCnt);
  CreateLudicList(LudicList);
  firstN(LudicList,25);
  writeln('There are ',CountLudic(LudicList,1000),' ludic numbers below 1000');
  LastLucid(LudicList,2000,5);
  LastLucid(LudicList,maxLudicCnt,5);
  triples(LudicList,250);//all-> (LudicList,LudicList[High(LudicList)].dNum);
END.


#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

const int luckySize = 60000;
std::vector<int> luckyEven(luckySize);
std::vector<int> luckyOdd(luckySize);

void init() {
    for (int i = 0; i < luckySize; ++i) {
        luckyEven[i] = i * 2 + 2;
        luckyOdd[i] = i * 2 + 1;
    }
}

void filterLuckyEven() {
    for (size_t n = 2; n < luckyEven.size(); ++n) {
        int m = luckyEven[n - 1];
        int end = (luckyEven.size() / m) * m - 1;
        for (int j = end; j >= m - 1; j -= m) {
            std::copy(luckyEven.begin() + j + 1, luckyEven.end(), luckyEven.begin() + j);
            luckyEven.pop_back();
        }
    }
}

void filterLuckyOdd() {
    for (size_t n = 2; n < luckyOdd.size(); ++n) {
        int m = luckyOdd[n - 1];
        int end = (luckyOdd.size() / m) * m - 1;
        for (int j = end; j >= m - 1; j -= m) {
            std::copy(luckyOdd.begin() + j + 1, luckyOdd.end(), luckyOdd.begin() + j);
            luckyOdd.pop_back();
        }
    }
}

void printBetween(size_t j, size_t k, bool even) {
    std::ostream_iterator<int> out_it{ std::cout, ", " };

    if (even) {
        size_t max = luckyEven.back();
        if (j > max || k > max) {
            std::cerr << "At least one are is too big\n";
            exit(EXIT_FAILURE);
        }

        std::cout << "Lucky even numbers between " << j << " and " << k << " are: ";
        std::copy_if(luckyEven.begin(), luckyEven.end(), out_it, [j, k](size_t n) {
            return j <= n && n <= k;
        });
    } else {
        size_t max = luckyOdd.back();
        if (j > max || k > max) {
            std::cerr << "At least one are is too big\n";
            exit(EXIT_FAILURE);
        }

        std::cout << "Lucky numbers between " << j << " and " << k << " are: ";
        std::copy_if(luckyOdd.begin(), luckyOdd.end(), out_it, [j, k](size_t n) {
            return j <= n && n <= k;
        });
    }
    std::cout << '\n';
}

void printRange(size_t j, size_t k, bool even) {
    std::ostream_iterator<int> out_it{ std::cout, ", " };
    if (even) {
        if (k >= luckyEven.size()) {
            std::cerr << "The argument is too large\n";
            exit(EXIT_FAILURE);
        }
        std::cout << "Lucky even numbers " << j << " to " << k << " are: ";
        std::copy(luckyEven.begin() + j - 1, luckyEven.begin() + k, out_it);
    } else {
        if (k >= luckyOdd.size()) {
            std::cerr << "The argument is too large\n";
            exit(EXIT_FAILURE);
        }
        std::cout << "Lucky numbers " << j << " to " << k << " are: ";
        std::copy(luckyOdd.begin() + j - 1, luckyOdd.begin() + k, out_it);
    }
}

void printSingle(size_t j, bool even) {
    if (even) {
        if (j >= luckyEven.size()) {
            std::cerr << "The argument is too large\n";
            exit(EXIT_FAILURE);
        }
        std::cout << "Lucky even number " << j << "=" << luckyEven[j - 1] << '\n';
    } else {
        if (j >= luckyOdd.size()) {
            std::cerr << "The argument is too large\n";
            exit(EXIT_FAILURE);
        }
        std::cout << "Lucky number " << j << "=" << luckyOdd[j - 1] << '\n';
    }
}

void help() {
    std::cout << "./lucky j [k] [--lucky|--evenLucky]\n";
    std::cout << "\n";
    std::cout << "       argument(s)        |  what is displayed\n";
    std::cout << "==============================================\n";
    std::cout << "-j=m                      |  mth lucky number\n";
    std::cout << "-j=m  --lucky             |  mth lucky number\n";
    std::cout << "-j=m  --evenLucky         |  mth even lucky number\n";
    std::cout << "-j=m  -k=n                |  mth through nth (inclusive) lucky numbers\n";
    std::cout << "-j=m  -k=n  --lucky       |  mth through nth (inclusive) lucky numbers\n";
    std::cout << "-j=m  -k=n  --evenLucky   |  mth through nth (inclusive) even lucky numbers\n";
    std::cout << "-j=m  -k=-n               |  all lucky numbers in the range [m, n]\n";
    std::cout << "-j=m  -k=-n  --lucky      |  all lucky numbers in the range [m, n]\n";
    std::cout << "-j=m  -k=-n  --evenLucky  |  all even lucky numbers in the range [m, n]\n";
}

int main(int argc, char **argv) {
    bool evenLucky = false;
    int j = 0;
    int k = 0;

    // skip arg 0, because that is just the executable name
    if (argc < 2) {
        help();
        exit(EXIT_FAILURE);
    }

    bool good = false;
    for (int i = 1; i < argc; ++i) {
        if ('-' == argv[i][0]) {
            if ('-' == argv[i][1]) {
                // long args
                if (0 == strcmp("--lucky", argv[i])) {
                    evenLucky = false;
                } else if (0 == strcmp("--evenLucky", argv[i])) {
                    evenLucky = true;
                } else {
                    std::cerr << "Unknown long argument: [" << argv[i] << "]\n";
                    exit(EXIT_FAILURE);
                }
            } else {
                // short args
                if ('j' == argv[i][1] && '=' == argv[i][2] && argv[i][3] != 0) {
                    good = true;
                    j = atoi(&argv[i][3]);
                } else if ('k' == argv[i][1] && '=' == argv[i][2]) {
                    k = atoi(&argv[i][3]);
                } else {
                    std::cerr << "Unknown short argument: " << argv[i] << '\n';
                    exit(EXIT_FAILURE);
                }
            }
        } else {
            std::cerr << "Unknown argument: " << argv[i] << '\n';
            exit(EXIT_FAILURE);
        }
    }
    if (!good) {
        help();
        exit(EXIT_FAILURE);
    }

    init();
    filterLuckyEven();
    filterLuckyOdd();
    if (k > 0) {
        printRange(j, k, evenLucky);
    } else if (k < 0) {
        printBetween(j, -k, evenLucky);
    } else {
        printSingle(j, evenLucky);
    }

    return 0;
}


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

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

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

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

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

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

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

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

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

}

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

say 'First 25:       ', join ' ', ludic(count => 25);
say 'Count < 1000:   ', scalar ludic(max => 1000);
say '2000..2005th:   ', join ' ', (ludic(count => 2005))[1999 .. 2004];
say 'triplets < 250: ', join ' ',
                        map { '(' . join(' ',$_, $_ + 2, $_ + 6) . ')' }
                        sort { $a <=> $b } @triplet;


import std.algorithm;
import std.concurrency;
import std.conv;
import std.getopt;
import std.range;
import std.stdio;

auto lucky(bool even, int nmax=200_000) {
    import std.container.array;

    int start = even ? 2 : 1;

    return new Generator!int({
        auto ln = make!(Array!int)(iota(start,nmax,2));

        // yield the first number
        yield(ln[0]);

        int n=1;
        for(; n<ln.length/2+1; n++) {
            yield(ln[n]);

            int step = ln[n]-1;

            // remove the non-lucky numbers related to the current lucky number
            for (int i=step; i<ln.length; i+=step) {
                ln.linearRemove(ln[].drop(i).take(1));
            }
        }

        // yield all remaining values
        foreach(val; ln[n..$]) {
            yield(val);
        }
    });
}

void help(Option[] opt) {
    defaultGetoptPrinter("./lucky j [k] [--lucky|--evenLucky]", opt);

    writeln;
    writeln("       argument(s)        |  what is displayed");
    writeln("==============================================");
    writeln("-j=m                      |  mth lucky number");
    writeln("-j=m  --lucky             |  mth lucky number");
    writeln("-j=m  --evenLucky         |  mth even lucky number");
    writeln("-j=m  -k=n                |  mth through nth (inclusive) lucky numbers");
    writeln("-j=m  -k=n  --lucky       |  mth through nth (inclusive) lucky numbers");
    writeln("-j=m  -k=n  --evenLucky   |  mth through nth (inclusive) even lucky numbers");
    writeln("-j=m  -k=-n               |  all lucky numbers in the range [m, n]");
    writeln("-j=m  -k=-n  --lucky      |  all lucky numbers in the range [m, n]");
    writeln("-j=m  -k=-n  --evenLucky  |  all even lucky numbers in the range [m, n]");
}

void main(string[] args) {
    int j;
    int k;
    bool evenLucky = false;

    void luckyOpt() {
        evenLucky = false;
    }
    auto helpInformation = getopt(
        args,
        std.getopt.config.passThrough,
        std.getopt.config.required,
        "j", "The starting point to generate lucky numbers", &j,
        "k", "The ending point for generating lucky numbers", &k,
        "lucky", "Specify to generate a list of lucky numbers", &luckyOpt,
        "evenLucky", "Specify to generate a list of even lucky numbers", &evenLucky
    );

    if (helpInformation.helpWanted) {
        help(helpInformation.options);
        return;
    }

    if (k>0) {
        lucky(evenLucky).drop(j-1).take(k-j+1).writeln;
    } else if (k<0) {
        auto f = (int a) => j<=a && a<=-k;
        lucky(evenLucky, -k).filter!f.writeln;
    } else {
        lucky(evenLucky).drop(j-1).take(1).writeln;
    }
}


constant LUMAX = 25000
sequence ludic = repeat(1,LUMAX)
integer n
for i=2 to LUMAX/2 do
    if ludic[i] then
        n = 0
        for j=i+1 to LUMAX do
            n += ludic[j]
            if n=i then
                ludic[j] = 0
                n = 0
            end if
        end for
    end if
end for

sequence s = {}
for i=1 to LUMAX do
    if ludic[i] then
        s &= i
        if length(s)=25 then exit end if
    end if
end for
printf(1,"First 25 Ludic numbers: %s\n",{sprint(s)})
printf(1,"Ludic numbers below 1000: %d\n",{sum(ludic[1..1000])})
s = {}
n = 0
for i=1 to LUMAX do
    if ludic[i] then
        n += 1
        if n>=2000 then
            s &= i
            if n=2005 then exit end if
        end if
    end if
end for
printf(1,"Ludic numbers 2000 to 2005: %s\n",{sprint(s)})
s = {}
for i=1 to 243 do
    if ludic[i] and ludic[i+2] and ludic[i+6] then
       s = append(s,{i,i+2,i+6})
    end if
end for
printf(1,"There are %d Ludic triplets below 250: %s\n",{length(s),sprint(s)})


// Odd and Even Lucky Numbers. Nigel Galloway: October 3rd., 2020
let rec fN i g e l=seq{yield! i|>Seq.skip g|>Seq.take(e-g-1)
                       let n=Seq.chunkBySize e i|>Seq.collect(Seq.take(e-1)) in yield! fN n (e-1) (Seq.item l n) (l+1)}
let oLuck,eLuck=let rec fG g=seq{yield g; yield! fG(g+2)} in (fN(fG 1) 0 3 2,fN(fG 2) 0 4 2)


package main

import (
    "fmt"
    "log"
    "os"
    "strconv"
    "strings"
)

const luckySize = 60000

var luckyOdd = make([]int, luckySize)
var luckyEven = make([]int, luckySize)

func init() {
    for i := 0; i < luckySize; i++ {
        luckyOdd[i] = i*2 + 1
        luckyEven[i] = i*2 + 2
    }
}

func filterLuckyOdd() {
    for n := 2; n < len(luckyOdd); n++ {
        m := luckyOdd[n-1]
        end := (len(luckyOdd)/m)*m - 1
        for j := end; j >= m-1; j -= m {
            copy(luckyOdd[j:], luckyOdd[j+1:])
            luckyOdd = luckyOdd[:len(luckyOdd)-1]
        }
    }
}

func filterLuckyEven() {
    for n := 2; n < len(luckyEven); n++ {
        m := luckyEven[n-1]
        end := (len(luckyEven)/m)*m - 1
        for j := end; j >= m-1; j -= m {
            copy(luckyEven[j:], luckyEven[j+1:])
            luckyEven = luckyEven[:len(luckyEven)-1]
        }
    }
}

func printSingle(j int, odd bool) error {
    if odd {
        if j >= len(luckyOdd) {
            return fmt.Errorf("the argument, %d, is too big", j)
        }
        fmt.Println("Lucky number", j, "=", luckyOdd[j-1])
    } else {
        if j >= len(luckyEven) {
            return fmt.Errorf("the argument, %d, is too big", j)
        }
        fmt.Println("Lucky even number", j, "=", luckyEven[j-1])
    }
    return nil
}

func printRange(j, k int, odd bool) error {
    if odd {
        if k >= len(luckyOdd) {
            return fmt.Errorf("the argument, %d, is too big", k)
        }
        fmt.Println("Lucky numbers", j, "to", k, "are:")
        fmt.Println(luckyOdd[j-1 : k])
    } else {
        if k >= len(luckyEven) {
            return fmt.Errorf("the argument, %d, is too big", k)
        }
        fmt.Println("Lucky even numbers", j, "to", k, "are:")
        fmt.Println(luckyEven[j-1 : k])
    }
    return nil
}

func printBetween(j, k int, odd bool) error {
    var r []int
    if odd {
        max := luckyOdd[len(luckyOdd)-1]
        if j > max || k > max {
            return fmt.Errorf("at least one argument, %d or %d, is too big", j, k)
        }
        for _, num := range luckyOdd {
            if num < j {
                continue
            }
            if num > k {
                break
            }
            r = append(r, num)
        }
        fmt.Println("Lucky numbers between", j, "and", k, "are:")
        fmt.Println(r)
    } else {
        max := luckyEven[len(luckyEven)-1]
        if j > max || k > max {
            return fmt.Errorf("at least one argument, %d or %d, is too big", j, k)
        }
        for _, num := range luckyEven {
            if num < j {
                continue
            }
            if num > k {
                break
            }
            r = append(r, num)
        }
        fmt.Println("Lucky even numbers between", j, "and", k, "are:")
        fmt.Println(r)
    }
    return nil
}

func main() {
    nargs := len(os.Args)
    if nargs < 2 || nargs > 4 {
        log.Fatal("there must be between 1 and 3 command line arguments")
    }
    filterLuckyOdd()
    filterLuckyEven()
    j, err := strconv.Atoi(os.Args[1])
    if err != nil || j < 1 {
        log.Fatalf("first argument, %s, must be a positive integer", os.Args[1])
    }
    if nargs == 2 {
        if err := printSingle(j, true); err != nil {
            log.Fatal(err)
        }
        return
    }

    if nargs == 3 {
        k, err := strconv.Atoi(os.Args[2])
        if err != nil {
            log.Fatalf("second argument, %s, must be an integer", os.Args[2])
        }
        if k >= 0 {
            if j > k {
                log.Fatalf("second argument, %d, can't be less than first, %d", k, j)
            }
            if err := printRange(j, k, true); err != nil {
                log.Fatal(err)
            }
        } else {
            l := -k
            if j > l {
                log.Fatalf("second argument, %d, can't be less in absolute value than first, %d", k, j)
            }
            if err := printBetween(j, l, true); err != nil {
                log.Fatal(err)
            }
        }
        return
    }

    var odd bool
    switch lucky := strings.ToLower(os.Args[3]); lucky {
    case "lucky":
        odd = true
    case "evenlucky":
        odd = false
    default:
        log.Fatalf("third argument, %s, is invalid", os.Args[3])
    }
    if os.Args[2] == "," {
        if err := printSingle(j, odd); err != nil {
            log.Fatal(err)
        }
        return
    }

    k, err := strconv.Atoi(os.Args[2])
    if err != nil {
        log.Fatal("second argument must be an integer or a comma")
    }
    if k >= 0 {
        if j > k {
            log.Fatalf("second argument, %d, can't be less than first, %d", k, j)
        }
        if err := printRange(j, k, odd); err != nil {
            log.Fatal(err)
        }
    } else {
        l := -k
        if j > l {
            log.Fatalf("second argument, %d, can't be less in absolute value than first, %d", k, j)
        }
        if err := printBetween(j, l, odd); err != nil {
            log.Fatal(err)
        }
    }
}


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

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

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


(de drop (Lst)
   (let N (car Lst)
      (make
         (for (I . X) (cdr Lst)
            (unless (=0 (% I N)) (link X)) ) ) ) )

(de comb (M Lst)
   (cond
      ((=0 M) '(NIL))
      ((not Lst))
      (T
         (conc
            (mapcar
               '((Y) (cons (car Lst) Y))
               (comb (dec M) (cdr Lst)) )
            (comb M (cdr Lst)) ) ) ) )

(de ludic (N)
   (let Ludic (range 1 100000)
      (make
         (link (pop 'Ludic))
         (do (dec N)
            (link (car Ludic))
            (setq Ludic (drop Ludic)) ) ) ) )

(let L (ludic 2005)
   (println (head 25 L))
   (println (cnt '((X) (< X 1000)) L))
   (println (tail 6 L))
   (println
      (filter
         '((Lst)
            (and
              (= (+ 2 (car Lst)) (cadr Lst))
              (= (+ 6 (car Lst)) (caddr Lst)) ) )
         (comb
            3
            (filter '((X) (< X 250)) L) ) ) ) )

(bye)


with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO.Unbounded_IO; use Ada.Text_IO.Unbounded_IO;

procedure Main is
   procedure print_range(start : integer; stop : integer; step : integer) is
      Num : Integer := start;
   begin
      Put("Range(" & start'Image & ", " & stop'image &
            ", " & step'image & ") => ");
      if stop < start then
         Put_Line("Error: stop must be no less than start!");
      elsif step not in positive then
         Put_Line("Error: increment must be greater than 0!");
      elsif start = stop then
         Put_Line(start'image);
      else
         while num <= stop loop
            Put(num'Image);
            num := num + step;
         end loop;
         New_Line;
      end if;
   end print_range;

   type test_record is record
      start   : integer;
      stop    : integer;
      step    : integer;
      comment : unbounded_string := null_unbounded_string;
   end record;

   tests : array(1..9) of test_record :=
     ( 1 => (-2, 2, 1, To_Unbounded_String("Normal")),
       2 => (-2, 2, 0, To_Unbounded_String("Zero increment")),
       3 => (-2, 2, -1, To_Unbounded_String("Increments away from stop value")),
       4 => (-2, 2, 10, To_Unbounded_String("First increment is beyond stop value")),
       5 => (2, -1, 1, To_Unbounded_String("Start more than stop: positive increment")),
       6 => (2, 2, 1, To_Unbounded_String("Start equal stop: positive increment")),
       7 => (2, 2, -1, To_Unbounded_String("Start equal stop: negative increment")),
       8 => (2, 2, 0, To_Unbounded_String("Start equal stop: zero increment")),
       9 => (0, 0, 0, To_Unbounded_String("Start equal stop equal zero: zero increment")));

begin
   for test of tests loop
      Put(Test.Comment); Put(" : ");
      print_range(test.start, test.stop, test.step);
      New_line;
   end loop;
end Main;


begin
    % sets the first n elements of s to the sequences of values specified by start, stop and increment    %
    % s( 0 ) is set to the number of elements of s that have been set, in case the sequence ends before n %
    procedure sequence ( integer array s ( * )
                       ; integer value n, start, stop, increment
                       ) ;
    begin
        integer sPos;
        for j := 0 until n do s( j ) := 0;
        sPos  := 1;
        for j := start step increment until stop do begin
            if sPos > n then goto done;
               s( sPos ) := j;
               s( 0    ) := s( 0 ) + 1;
               sPos      := sPos + 1;
       end for_j ;
done:
    end sequence ;
    % tests the sequence procedure %
    procedure testSequence( integer    value start, stop, increment
                          ; string(48) value legend
                          ) ;
    begin
        integer array s ( 0 :: 10 );
        sequence( s, 10, start, stop, increment );
        s_w := 0; % set output formating %
        i_w := 4;
        write( legend, ": " );
        for i := 1 until s( 0 ) do writeon( s( i ) )
    end testSequence ;
    % task trest cases %
    testSequence( -2,  2,  1, "Normal"                                      );
    testSequence( -2,  2,  0, "Zero increment"                              );
    testSequence( -2,  2, -1, "Increments away from stop value"             );
    testSequence( -2,  2, 10, "First increment is beyond stop value"        );
    testSequence(  2, -2,  1, "Start more than stop: positive increment"    );
    testSequence(  2,  2,  1, "Start equal stop: positive increment"        );
    testSequence(  2,  2, -1, "Start equal stop: negative increment"        );
    testSequence(  2,  2,  0, "Start equal stop: zero increment"            );
    testSequence(  0,  0,  0, "Start equal stop equal zero: zero increment" )
end.


0 LIMIT = 10 :MAX=1E37
10 DATA-2,2,1,NORMAL
20 DATA-2,2,0,ZERO INCREMENT
30 DATA-2,2,-1,INCREMENTS AWAY FROM STOP VALUE
40 DATA-2,2,10,FIRST INCREMENT IS BEYOND STOP VALUE
50 DATA2,-2,1,"START MORE THAN STOP: POSITIVE INCREMENT
60 DATA2,2,1,"START EQUAL STOP: POSITIVE INCREMENT
70 DATA2,2,-1,"START EQUAL STOP: NEGATIVE INCREMENT
80 DATA2,2,0,"START EQUAL STOP: ZERO INCREMENT
90 DATA0,0,0,"START EQUAL STOP EQUAL ZERO: ZERO INCREMENT
100 FOR I = 1 TO 9
110     READ START,FINISH,INCR,COMMENT$
120     PRINT CHR$(13)COMMENT$
130     LAST = FINISH
140 REM D = SGN(FINISH - START)
150 REM IF D AND NOT (D = SGN(INCR)) THEN LAST = SGN(INCR)*MAX
160     PRINT TAB(5)CHR$(91)" "MID$(" ",(START<0)+1)START" TO "MID$(" ",(FINISH<0)+1)FINISH" STEP "MID$(" ",(INCR<0)+1)INCR" ]    ";
170     COUNT = 0
180     PRINT MID$(" ",(START<0)+1);
190     FOR J = START TO LAST STEP INCR
200         PRINT MID$(" ",(COUNT=0)+1)J;
210         IF COUNT < LIMIT THEN COUNT = COUNT + 1 : NEXT J
220     IF COUNT = LIMIT THEN PRINT " ... ";:if ABS(LAST) = MAX THEN PRINT MID$("-",SGN(LAST)+2,1)"INFINITY";
230 NEXT I


import System.Environment
import Text.Regex.Posix

data Lucky = Lucky | EvenLucky

helpMessage :: IO ()
helpMessage = do
  putStrLn "                           what is displayed  (on a single line)"
  putStrLn "     argument(s)              (optional verbiage is encouraged)"
  putStrLn "======================|==================================================="
  putStrLn " j                    | Jth       lucky number                            "
  putStrLn " j  ,          lucky  | Jth       lucky number                            "
  putStrLn " j  ,      evenLucky  | Jth  even lucky number                            "
  putStrLn "                                                                          "
  putStrLn " j  k                 | Jth  through  Kth (inclusive)       lucky numbers "
  putStrLn " j  k          lucky  | Jth  through  Kth (inclusive)       lucky numbers "
  putStrLn " j  k      evenlucky  | Jth  through  Kth (inclusive)  even lucky numbers "
  putStrLn "                                                                          "
  putStrLn " j -k                 | all       lucky numbers in the range  j -> |k|    "
  putStrLn " j -k          lucky  | all       lucky numbers in the range  j -> |k|    "
  putStrLn " j -k      evenlucky  | all  even lucky numbers in the range  j -> |k|    "
  putStrLn "======================|==================================================="

oddNumbers :: [Int]
oddNumbers = filter odd [1..]

evenNumbers :: [Int]
evenNumbers = filter even [1..]

luckyNumbers :: [Int] -> [Int]
luckyNumbers xs =
  let i = 3 in
  sieve i xs
    where
      sieve i (ln:s:xs) =
        ln : sieve (i + 1) (s : [x | (n, x) <- zip [i..] xs, rem n s /= 0])

nth :: Int -> Lucky -> Int
nth j Lucky     = luckyNumbers oddNumbers !! (j-1)
nth j EvenLucky = luckyNumbers evenNumbers !! (j-1)

range :: Int -> Int -> Lucky -> [Int]
range x x2 Lucky     = drop (x-1) (take x2 (luckyNumbers oddNumbers))
range x x2 EvenLucky = drop (x-1) (take x2 (luckyNumbers evenNumbers))

interval :: Int -> Int -> Lucky -> [Int]
interval x x2 Lucky     = dropWhile (<x) (takeWhile (<=x2) (luckyNumbers oddNumbers))
interval x x2 EvenLucky = dropWhile (<x) (takeWhile (<=x2) (luckyNumbers evenNumbers))

lucky :: [String] -> Lucky
lucky xs =
  if "evenLucky" `elem` xs
   then EvenLucky
   else Lucky

readn :: String -> Int
readn s = read s :: Int

isInt :: String -> Bool
isInt s = not (null (s =~ "-?[0-9]{0,10}" :: String))

main :: IO ()
main = do
  args <- getArgs
  if head args == "--help" || null args
    then
      helpMessage
    else
      let l = lucky args in
      case map readn (filter isInt args) of
        [] -> do
          putStrLn "Invalid input, missing arguments"
          putStrLn "Type --help"
        [x] -> print (nth x l)
        [x, x2] -> if x2 > 0
          then print (range x x2 l)
          else print (interval x (-x2) l)
        _ -> do
          putStrLn "Invalid input, wrong number of arguments"
          putStrLn "Type --help"


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

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

   do forever;

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

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

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

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

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

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

end Ludic;

call Ludic;

end Ludic_numbers;


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

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

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

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

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

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

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

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

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

END;
/


# syntax: GAWK -f LOOPS_WRONG_RANGES.AWK
BEGIN {
    arr[++n] = "-2, 2, 1,Normal"
    arr[++n] = "-2, 2, 0,Zero increment"
    arr[++n] = "-2, 2,-1,Increments away from stop value"
    arr[++n] = "-2, 2,10,First increment is beyond stop value"
    arr[++n] = " 2,-2, 1,Start more than stop: positive increment"
    arr[++n] = " 2, 2, 1,Start equal stop: positive increment"
    arr[++n] = " 2, 2,-1,Start equal stop: negative increment"
    arr[++n] = " 2, 2, 0,Start equal stop: zero increment"
    arr[++n] = " 0, 0, 0,Start equal stop equal zero: zero increment"
    print("start,stop,increment,comment")
    for (i=1; i<=n; i++) {
      split(arr[i],A,",")
      printf("%-52s : ",arr[i])
      count = 0
      for (j=A[1]; j<=A[2] && count<10; j+=A[3]) {
        printf("%d ",j)
        count++
      }
      printf("\n")
    }
    exit(0)
}


arraybase 1
dim start(9) : dim fin(9) : dim inc(9) : dim cmt$(9)
start[1] = -2 : fin[1] =  2 : inc[1] =  1 : cmt$[1] = "Normal"
start[2] = -2 : fin[2] =  2 : inc[2] =  0 : cmt$[2] = "Zero increment"
start[3] = -2 : fin[3] =  2 : inc[3] = -1 : cmt$[3] = "Increments away from stop value"
start[4] = -2 : fin[4] =  2 : inc[4] = 10 : cmt$[4] = "First increment is beyond stop value"
start[5] =  2 : fin[5] = -2 : inc[5] =  1 : cmt$[5] = "Start more than stop: positive increment"
start[6] =  2 : fin[6] =  2 : inc[6] =  1 : cmt$[6] = "Start equal stop: positive increment"
start[7] =  2 : fin[7] =  2 : inc[7] = -1 : cmt$[7] = "Start equal stop: negative increment"
start[8] =  2 : fin[8] =  2 : inc[8] =  0 : cmt$[8] = "Start equal stop: zero increment"
start[9] =  0 : fin[9] =  0 : inc[9] =  0 : cmt$[9] = "Start equal stop equal zero: zero increment"

for i = 1 to 9
    contar = 0
    print cmt$[i]
    print "  Bucle de "; start[i]; " a "; fin[i]; " en incrementos de "; inc[i]
    for vr = start[i] to fin[i] step inc[i]
        print "        Índice del bucle = "; vr
        contar = contar + 1
        if contar = 10 then
            print "        Saliendo de un bucle infinito"
            exit for
        endif
    next vr
    print "  Bucle terminado" & chr(10) & chr(10)
next i
end


luckySeq=:3 :0
  1 luckySeq y
:
  len=.0
  nth=.0
  seq=.x+2*i.4*y
  while.  len~:#seq do.
    len=. #seq
    nth=. nth+1
    seq=. nth exclude seq
  end.
)

exclude=: ] #~ 1 - #@] $ [email protected]{ {. 1:

lucky=:''
evenLucky=:0
program=:3 :0
  range=: |y-.0
  seq=. (1+0 e.y) luckySeq >./range
  if. 0><./y do.
    (#~ e.&(thru/range)) seq
  else.
    (<:thru/range) { seq
  end.
)

thru=: <./ + [email protected](+*)@-~


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

public class LuckyNumbers {

    private static int MAX = 200000;
    private static List<Integer> luckyEven = luckyNumbers(MAX, true);
    private static List<Integer> luckyOdd = luckyNumbers(MAX, false);

    public static void main(String[] args) {
        //  Case 1 and 2
        if ( args.length == 1 || ( args.length == 2 && args[1].compareTo("lucky") == 0 ) ) {
            int n = Integer.parseInt(args[0]);
            System.out.printf("LuckyNumber(%d) = %d%n", n, luckyOdd.get(n-1));
        }
        //  Case 3
        else if ( args.length == 2 && args[1].compareTo("evenLucky") == 0 ) {
            int n = Integer.parseInt(args[0]);
            System.out.printf("EvenLuckyNumber(%d) = %d%n", n, luckyEven.get(n-1));
        }
        //  Case 4 through 9
        else if ( args.length == 2 || args.length == 3 ) {
            int j = Integer.parseInt(args[0]);
            int k = Integer.parseInt(args[1]);
            //  Case 4 and 5
            if ( ( args.length == 2 && k > 0 ) || (args.length == 3 && k > 0 && args[2].compareTo("lucky") == 0 ) ) {
                System.out.printf("LuckyNumber(%d) through LuckyNumber(%d) = %s%n", j, k, luckyOdd.subList(j-1, k));
            }
            //  Case 6
            else if ( args.length == 3 && k > 0 && args[2].compareTo("evenLucky") == 0 ) {
                System.out.printf("EvenLuckyNumber(%d) through EvenLuckyNumber(%d) = %s%n", j, k, luckyEven.subList(j-1, k));
            }
            //  Case 7 and 8
            else if ( ( args.length == 2 && k < 0 ) || (args.length == 3 && k < 0 && args[2].compareTo("lucky") == 0 ) ) {
                int n = Collections.binarySearch(luckyOdd, j);
                int m = Collections.binarySearch(luckyOdd, -k);
                System.out.printf("Lucky Numbers in the range %d to %d inclusive = %s%n", j, -k, luckyOdd.subList(n < 0 ? -n-1 : n, m < 0 ? -m-1 : m+1));
            }
            //  Case 9
            else if ( args.length == 3 && k < 0 && args[2].compareTo("evenLucky") == 0 ) {
                int n = Collections.binarySearch(luckyEven, j);
                int m = Collections.binarySearch(luckyEven, -k);
                System.out.printf("Even Lucky Numbers in the range %d to %d inclusive = %s%n", j, -k, luckyEven.subList(n < 0 ? -n-1 : n, m < 0 ? -m-1 : m+1));
            }
        }
    }

    private static List<Integer> luckyNumbers(int max, boolean even) {
        List<Integer> luckyList = new ArrayList<>();
        for ( int i = even ? 2 : 1 ; i <= max ; i += 2 ) {
            luckyList.add(i);
        }
        int start = 1;
        boolean removed = true;
        while ( removed ) {
            removed = false;
            int increment = luckyList.get(start);
            List<Integer> remove = new ArrayList<>();
            for ( int i = increment-1 ; i < luckyList.size() ; i += increment ) {
                remove.add(0, i);
                removed = true;
            }
            for ( int i : remove ) {
                luckyList.remove(i);
            }
            start++;
        }
        return luckyList;
    }

}


#  Start with a pool large enough to meet the requirements
$Pool = [System.Collections.ArrayList]( 2..22000 )

#  Start with 1, because it's grandfathered in
$Ludic = @( 1 )

#  While the size of the pool is still larger than the next Ludic number...
While ( $Pool.Count -gt $Pool[0] )
    {
    #  Add the next Ludic number to the list
    $Ludic += $Pool[0]

    #  Remove from the pool all entries whose index is a multiple of the next Ludic number
    [math]::Truncate( ( $Pool.Count - 1 )/ $Pool[0])..0 | ForEach { $Pool.RemoveAt( $_ * $Pool[0] ) }
    }

#  Add the rest of the numbers in the pool to the list of Ludic numbers
$Ludic += $Pool.ToArray()


#include <stdio.h>

#define TRUE 1
#define FALSE 0

typedef int bool;

typedef struct {
    int start, stop, incr;
    const char *comment;
} S;

S examples[9] = {
    {-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"}
};

int main() {
    int i, j, c;
    bool empty;
    S s;
    const int limit = 10;
    for (i = 0; i < 9; ++i) {
        s = examples[i];
        printf("%s\n", s.comment);
        printf("Range(%d, %d, %d) -> [", s.start, s.stop, s.incr);
        empty = TRUE;
        for (j = s.start, c = 0; j <= s.stop && c < limit; j += s.incr, ++c) {
            printf("%d ", j);
            empty = FALSE;
        }
        if (!empty) printf("\b");
        printf("]\n\n");
    }
    return 0;
}


using System;
using System.Collections.Generic;

static class Program
{
    static 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 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");
    }

    static IEnumerable<int> Range(int start, int stop, int increment)
    {
        // To replicate the (arguably more correct) behavior of VB.NET:
        //for (int i = start; increment >= 0 ? i <= stop : stop <= i; i += increment)

        // Decompiling the IL emitted by the VB compiler (uses shifting right by 31 as the signum function and bitwise xor in place of the conditional expression):
        //for (int i = start; ((increment >> 31) ^ i) <= ((increment >> 31) ^ stop); i += increment)

        // "Naïve" translation.
        for (int i = start; i <= stop; i += increment)
            yield return i;
    }

    static void Example(int start, int stop, int increment, string comment)
    {
        // Add a space, pad to length 50 with hyphens, and add another space.
        Console.Write((comment + " ").PadRight(50, '-') + " ");

        const int MAX_ITER = 9;

        int iteration = 0;
        foreach (int i in Range(start, stop, increment))
        {
            Console.Write("{0,2} ", i);

            if (++iteration > MAX_ITER) break;
        }

        Console.WriteLine();
    }
}


function luckyNumbers(opts={}) {
  /**************************************************************************\
  | OPTIONS                                                                  |
  |**************************************************************************|
  |   even ...... boolean ............. return even/uneven numbers           |
  |                                     (default: false)                     |
  |                                                                          |
  |   nth ....... number ............... return nth number                   |
  |                                                                          |
  |   through ... number ............... return numbers from #1 to number    |
  |               OR array[from, to] ... return numbers on index             |
  |                                      from array[from] to array[to]       |
  |                                                                          |
  |   range ..... array[from, to] ...... return numbers between from and to  |
  \**************************************************************************/

  opts.even =  opts.even || false;
  if (typeof opts.through == 'number') opts.through = [0, opts.through];
  let out = [],
      x = opts.even ? 2 : 1,
      max = opts.range ? opts.range[1] * 3
        : opts.through ? opts.through[1] * 12
        : opts.nth ? opts.nth * 15
        : 2000;

  for (x; x <= max; x = x+2) out.push(x);            // fill
  for (x = 1; x < Math.floor(out.length / 2); x++) { // sieve
    let i = out.length;
    while (i--)
      (i+1) % out[x] == 0 && out.splice(i, 1);
  }

  if (opts.nth) return out[opts.nth-1];
  if (opts.through) return out.slice(opts.through[0], opts.through[1]);
  if (opts.range) return out.filter(function(val) {
      return val >= opts.range[0] && val <= opts.range[1];
    });
  return out;
}

/* TESTING */
// blank
console.log( luckyNumbers() );
// showing the first twenty lucky numbers
console.log( luckyNumbers({through: 20}) );
// showing the first twenty even lucky numbers
console.log( luckyNumbers({even: true, through: 20}) );
// showing all lucky numbers between 6,000 and 6,100 (inclusive)
console.log( luckyNumbers({range: [6000, 6100]}) );
// showing all even lucky numbers in the same range as above
console.log( luckyNumbers({even: true, range: [6000, 6100]}) );
// showing the 10,000th lucky number (extra credit)
console.log( luckyNumbers({nth: 10000}) );
// showing the 10,000th even lucky number (extra credit)
console.log( luckyNumbers({even: true, nth: 10000}) );


EnableExplicit
If Not OpenConsole() : End 1 : EndIf

#NMAX=25000

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

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

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

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

PrintN("First 25 Ludic numbers: "     +r1$)
PrintN("Ludic numbers below 1000: "   +r2$)
PrintN("Ludic numbers 2000 to 2005: " +r3$)
PrintN("Ludic Triplets below 250: "   +r4$)
Input()
End


(dolist (lst '((-2  2  1 "Normal")	  ; Iterate the parameters list `start' `stop' `increment' and `comment'
	       (-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")))
  (do ((i (car lst) (incf i (caddr lst))) ; Initialize `start' and set `increment'
       (result ())			  ; Initialize the result list
       (loop-max 0 (incf loop-max)))	  ; Initialize a loop limit
      ((or (> i (cadr lst))		  ; Break condition to `stop'
	   (> loop-max 10))		  ; Break condition to loop limit
       (format t "~&~44a: ~{~3d ~}"	  ; Finally print
	       (cadddr lst)		  ; The `comment'
	       (reverse result)))	  ; The in(de)creased numbers into result
    (push i result)))			  ; Add the number to result


program Wrong_ranges;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

procedure Example(start, stop, Increment: Integer; comment: string);
var
  MAX_ITER, iteration, i: Integer;
begin
  Write((comment + ' ').PadRight(50, '-') + ' ');
  MAX_ITER := 9;
  iteration := 0;

  if Increment = 1 then
  begin
    for i := start to stop do
    begin
      Write(i: 2, ' ');
      inc(iteration);
      if iteration >= MAX_ITER then
        Break;
    end;
    Writeln;
    exit;
  end;

  if Increment = -1 then
  begin
    for i := start downto stop do
    begin
      Write(i: 2, ' ');
      inc(iteration);
      if iteration >= MAX_ITER then
        Break;
    end;
    Writeln;
    exit;
  end;

  Writeln('Not supported');
end;

begin
  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');
  Readln;
end.


using Base, StringDistances

struct Lucky
    start::Int
    nmax::Int
    Lucky(iseven, nmax) = new(iseven ? 2 : 1, nmax)
end

struct LuckyState
    nextindex::Int
    sequence::Vector{Int}
end

Base.eltype(iter::Lucky) = Int

function Base.iterate(iter::Lucky, state = LuckyState(1, collect(iter.start:2:iter.nmax)))
    if length(state.sequence) < state.nextindex
        return nothing
    elseif state.nextindex == 1
        return (iter.start, LuckyState(2, state.sequence))
    end
    result = state.sequence[state.nextindex]
    newsequence = Vector{Int}()
    for (i, el) in enumerate(state.sequence)
        if i % result != 0
            push!(newsequence, el)
        end
    end
    (result, LuckyState(state.nextindex + 1, newsequence))
end

function luckyindex(j, wanteven, k=0)
    topindex = max(j, k) + 4
    luck = Lucky(wanteven, topindex * 20)
    iter_result = iterate(luck)
    while iter_result != nothing
        (elem, state) = iter_result
        iter_result = iterate(luck, state)
        if iter_result != nothing && iter_result[2].nextindex > topindex
            return iter_result[2].sequence[k > j ? (j:k) : j]
        end
    end
    throw("Index $j out of range for nmax of $(luck.nmax).")
end

function luckyrange(j, k, wanteven)
    topvalue = max(j, k)
    luck = Lucky(wanteven, topvalue + 1)
    iter_result = iterate(luck)
    (elem, state) = iter_result # save next to last result
    while iter_result != nothing
        (elem, state) = iter_result
        iter_result = iterate(luck, state)
    end
    filter(x -> (j <= x <= k), state.sequence)
end

function helpdisplay(exitlevel=1)
    println("\n", PROGRAM_FILE, " j [-][k] [lucky|evenLucky]")
    println("\tj: index wanted or a starting point (index or value)",
            "\n\tk: optional ending point (index), \n\t-k: optional ending point (value)\n")
    helpstring =
""" | Argument(s)        |    What is printed                                  |
 |--------------------------------------------------------------------------|
 | j                  |  jth lucky number (required argument)               |
 | 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 value range [m, |k|]      |
 | j  -k  lucky       |  all lucky numbers in the value range [m, |k|]      |
 | j  -k  evenLucky   |  all even lucky numbers in the value range [m, |k|] |
 |--------------------------------------------------------------------------|\n\n"""

    println(helpstring)
    exit(exitlevel)
end

function parsecommandline()
    comma = false
    evenLucky = false
    range = false
    j = k = 0
    if length(ARGS) < 1
        helpdisplay()
    end
    for (pos, arg) in enumerate(ARGS)
        if pos == 1
            j = tryparse(Int, arg)
            if j == nothing
                println("The first argument must be a positive integer.\n")
                helpdisplay()
            end
        elseif pos == 2 || (pos == 3 && comma)
            k = tryparse(Int, arg)
            if k == nothing
                k = 0
                if arg == ","
                    comma = true
                    continue
                elseif arg == "lucky"
                    continue
                elseif arg == "evenLucky"
                    evenLucky = true
                elseif compare(Hamming(), arg, "lucky") > 0.4 || compare(Hamming(), arg, "evenLucky") > 0.4
                    println("Did you misspell \"lucky\" or \"evenLucky\"? Check capitalization.\n")
                    helpdisplay()
                else
                    helpdisplay()
                end
            elseif k < 0
                k = -k
                range = true
            end
        elseif pos == 3 || pos == 4 && comma
            if arg == ","
                comma = true
                continue
            elseif arg == "lucky"
                continue
            elseif arg == "evenLucky"
                evenLucky = true
            elseif compare(Hamming(), arg, "lucky") > 0.1 || compare(Hamming(), arg, "evenLucky") > 0.1
                println("Did you misspell "\lucky\" or "\evenLucky\"?\n\n")
                helpdisplay()
            else
                helpdisplay()
            end
        elseif arg == "lucky"
                continue
        elseif arg == "evenLucky"
                evenLucky = true
        else
            println("Too many arguments.\n")
            helpdisplay()
        end
    end
    (j, k, evenLucky, range)
end

function runopts()
    (j, k, evenLucky, range) = parsecommandline()
    if j < 1 || (k != 0 && j >= k)
        throw("Lucky number integer parameters out of range: $(typeof(j)), $j, $(typeof(k)), $k")
    end
    if range
        println(luckyrange(j, k, evenLucky))
    else
        println(luckyindex(j, evenLucky, k))
    end
end

runopts()


// version 1.1.51

typealias IAE = IllegalArgumentException

val luckyOdd  = MutableList(100000) { it * 2 + 1 }
val luckyEven = MutableList(100000) { it * 2 + 2 }

fun filterLuckyOdd() {
    var n = 2
    while (n < luckyOdd.size) {
        val m = luckyOdd[n - 1]
        val end = (luckyOdd.size / m) * m - 1
        for (j in end downTo m - 1 step m) luckyOdd.removeAt(j)
        n++
    }
}

fun filterLuckyEven() {
    var n = 2
    while (n < luckyEven.size) {
        val m = luckyEven[n - 1]
        val end = (luckyEven.size / m) * m - 1
        for (j in end downTo m - 1 step m) luckyEven.removeAt(j)
        n++
    }
}

fun printSingle(j: Int, odd: Boolean) {
    if (odd) {
        if (j >= luckyOdd.size) throw IAE("Argument is too big")
        println("Lucky number $j = ${luckyOdd[j - 1]}")
    }
    else {
        if (j >= luckyEven.size) throw IAE("Argument is too big")
        println("Lucky even number $j = ${luckyEven[j - 1]}")
    }
}

fun printRange(j: Int, k: Int, odd: Boolean) {
    if (odd) {
        if (k >= luckyOdd.size) throw IAE("Argument is too big")
        println("Lucky numbers $j to $k are:\n${luckyOdd.drop(j - 1).take(k - j + 1)}")
    }
    else {
        if (k >= luckyEven.size) throw IAE("Argument is too big")
        println("Lucky even numbers $j to $k are:\n${luckyEven.drop(j - 1).take(k - j + 1)}")
    }
}

fun printBetween(j: Int, k: Int, odd: Boolean) {
    val range = mutableListOf<Int>()
    if (odd) {
        val max = luckyOdd[luckyOdd.lastIndex]
        if (j > max || k > max) {
            throw IAE("At least one argument is too big")
        }
        for (num in luckyOdd) {
            if (num < j) continue
            if (num > k) break
            range.add(num)
        }
        println("Lucky numbers between $j and $k are:\n$range")
    }
    else {
        val max = luckyEven[luckyEven.lastIndex]
        if (j > max || k > max) {
            throw IAE("At least one argument is too big")
        }
        for (num in luckyEven) {
            if (num < j) continue
            if (num > k) break
            range.add(num)
        }
        println("Lucky even numbers between $j and $k are:\n$range")
    }
}

fun main(args: Array<String>) {
    if (args.size !in 1..3) throw IAE("There must be between 1 and 3 command line arguments")
    filterLuckyOdd()
    filterLuckyEven()
    val j = args[0].toIntOrNull()
    if (j == null || j < 1) throw IAE("First argument must be a positive integer")
    if (args.size == 1) { printSingle(j, true); return }

    if (args.size == 2) {
        val k = args[1].toIntOrNull()
        if (k == null) throw IAE("Second argument must be an integer")
        if (k >= 0) {
            if (j > k) throw IAE("Second argument can't be less than first")
            printRange(j, k, true)
        }
        else {
           val l = -k
            if (j > l) throw IAE("The second argument can't be less in absolute value than first")
            printBetween(j, l, true)
        }
        return
    }

    var odd =
        if (args[2].toLowerCase() == "lucky") true
        else if (args[2].toLowerCase() == "evenlucky") false
        else throw IAE("Third argument is invalid")

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

    val k = args[1].toIntOrNull()
    if (k == null) throw IAE("Second argument must be an integer or a comma")

    if (k >= 0) {
        if (j > k) throw IAE("Second argument can't be less than first")
        printRange(j, k, odd)
    }
    else {
        val l = -k
        if (j > l) throw IAE("The second argument can't be less in absolute value than first")
        printBetween(j, l, odd)
    }
}


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

ludics = [l for l in ludic()]

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

n = 250
triplets = [(x, x+2, x+6)
            for x in ludics
            if x+6 < n and x+2 in ludics and x+6 in ludics]
print('\nThere are %i triplets less than %i:\n  %r'
      % (len(triplets), n, triplets))


example
		-- Loops/Wrong ranges
	do
		⟳ ic:(-2 |..| 2) ¦ 				do_nothing ⟲ --  2 	2 	 1 	Normal
		⟳ ic:(-2 |..| 2).new_cursor + 0 ¦ 		do_nothing ⟲ -- -2 	2 	 0 	Zero increment
		⟳ ic:(-2 |..| 2).new_cursor - 1 ¦ 		do_nothing ⟲ -- -2 	2 	-1 	Increments away from stop value
		⟳ ic:(-2 |..| 2).new_cursor + 10 ¦ 		do_nothing ⟲ -- -2 	2 	10 	First increment is beyond stop value
		⟳ ic:(-2 |..| 2).new_cursor.reversed ¦ 		do_nothing ⟲ --  2 	-2 	 1 	Start more than stop: positive increment
		⟳ ic:(2 |..| 2) ¦ 				do_nothing ⟲ --  2 	2 	 1 	Start equal stop: positive increment
		⟳ ic:(2 |..| 2).new_cursor - 1 ¦ 		do_nothing ⟲ --  2 	2 	-1 	Start equal stop: negative increment
		⟳ ic:(2 |..| 2).new_cursor + 0 ¦ 		do_nothing ⟲ --  2 	2 	 0 	Start equal stop: zero increment
		⟳ ic:(0 |..| 0).new_cursor + 0 ¦ 		do_nothing ⟲ --  0 	0 	 0 	Start equal stop equal zero: zero increment
	end


USING: continuations formatting io kernel math.ranges
prettyprint sequences ;

: try-range ( from length step -- )
    [ <range> { } like . ]
    [ 4drop "Exception: divide by zero." print ] recover ;

{
    { -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 }
}
[
    first3
    [ "%2d %2d %2d <range>  =>  " printf ]
    [ try-range ] 3bi
] each


for a = -2 to  2 by  1 do !(a,' '); od;
for a = -2 to  2 by  0 do !(a,' '); od;
for a = -2 to  2 by -1 do !(a,' '); od;
for a = -2 to  2 by 10 do !(a,' '); od;
for a =  2 to -2 by  1 do !(a,' '); od;
for a =  2 to  2 by  1 do !(a,' '); od;
for a =  2 to  2 by -1 do !(a,' '); od;
for a =  2 to  2 by  0 do !(a,' '); od;
for a =  0 to  0 by  0 do !(a,' '); od;