Note that in the following explanation list indices are assumed to start at one.

Definition of lucky numbers
Lucky numbers are positive integers that are formed by:

 Form a list of all the positive odd integers > 0




1
,
3
,
5
,
7
,
9
,
11
,
13
,
15
,
17
,
19
,
21
,
23
,
25
,
27
,
29
,
31
,
33
,
35
,
37
,
39...


{\displaystyle 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39...}


 Return the first number from the list (which is 1).
 (Loop begins here)
 Note then return the second number from the list (which is 3).
 Discard every third, (as noted), number from the list to form the new list




1
,
3
,
7
,
9
,
13
,
15
,
19
,
21
,
25
,
27
,
31
,
33
,
37
,
39
,
43
,
45
,
49
,
51
,
55
,
57...


{\displaystyle 1,3,7,9,13,15,19,21,25,27,31,33,37,39,43,45,49,51,55,57...}


 (Expanding the loop a few more times...)
 Note then return the third number from the list (which is 7).
 Discard every 7th, (as noted), number from the list to form the new list




1
,
3
,
7
,
9
,
13
,
15
,
21
,
25
,
27
,
31
,
33
,
37
,
43
,
45
,
49
,
51
,
55
,
57
,
63
,
67...


{\displaystyle 1,3,7,9,13,15,21,25,27,31,33,37,43,45,49,51,55,57,63,67...}


 Note then return the 4th number from the list (which is 9).
 Discard every 9th, (as noted), number from the list to form the new list




1
,
3
,
7
,
9
,
13
,
15
,
21
,
25
,
31
,
33
,
37
,
43
,
45
,
49
,
51
,
55
,
63
,
67
,
69
,
73...


{\displaystyle 1,3,7,9,13,15,21,25,31,33,37,43,45,49,51,55,63,67,69,73...}


 Take the 5th, i.e. 13. Remove every 13th.
 Take the 6th, i.e. 15. Remove every 15th.
 Take the 7th, i.e. 21. Remove every 21th.
 Take the 8th, i.e. 25. Remove every 25th.
 (Rule for the loop)
 Note the 



n


{\displaystyle n}

th, which is 



m


{\displaystyle m}

.
 Remove every 



m


{\displaystyle m}

th.
 Increment 



n


{\displaystyle n}

.
Definition of even lucky numbers
This follows the same rules as the definition of lucky numbers above except for the very first step:

 Form a list of all the positive even integers > 0




2
,
4
,
6
,
8
,
10
,
12
,
14
,
16
,
18
,
20
,
22
,
24
,
26
,
28
,
30
,
32
,
34
,
36
,
38
,
40...


{\displaystyle 2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40...}


 Return the first number from the list (which is 2).
 (Loop begins here)
 Note then return the second number from the list (which is 4).
 Discard every 4th, (as noted), number from the list to form the new list




2
,
4
,
6
,
10
,
12
,
14
,
18
,
20
,
22
,
26
,
28
,
30
,
34
,
36
,
38
,
42
,
44
,
46
,
50
,
52...


{\displaystyle 2,4,6,10,12,14,18,20,22,26,28,30,34,36,38,42,44,46,50,52...}


 (Expanding the loop a few more times...)
 Note then return the third number from the list (which is 6).
 Discard every 6th, (as noted), number from the list to form the new list




2
,
4
,
6
,
10
,
12
,
18
,
20
,
22
,
26
,
28
,
34
,
36
,
38
,
42
,
44
,
50
,
52
,
54
,
58
,
60...


{\displaystyle 2,4,6,10,12,18,20,22,26,28,34,36,38,42,44,50,52,54,58,60...}


 Take the 4th, i.e. 10. Remove every 10th.
 Take the 5th, i.e. 12. Remove every 12th.
 (Rule for the loop)
 Note the 



n


{\displaystyle n}

th, which is 



m


{\displaystyle m}

.
 Remove every 



m


{\displaystyle m}

th.
 Increment 



n


{\displaystyle n}

.
Task requirements
 Write one or two subroutines (functions) to generate lucky numbers and even lucky numbers 
 Write a command-line interface to allow selection of which kind of numbers and which number(s). Since input is from the command line, tests should be made for the common errors:
 missing arguments
 too many arguments
 number (or numbers) aren't legal
 misspelled argument (lucky or evenLucky)
 The command line handling should:
 support mixed case handling of the (non-numeric) arguments
 support printing a particular number
 support printing a range of numbers by their index
 support printing a range of numbers by their values
 The resulting list of numbers should be printed on a single line.

The program should support the arguments:

                             what is displayed  (on a single line)
       argument(s)              (optional verbiage is encouraged)
  ╔═══════════════════╦════════════════════════════════════════════════════╗
  ║  j                ║  Jth       lucky number                            ║
  ║  j  ,      lucky  ║  Jth       lucky number                            ║
  ║  j  ,  evenLucky  ║  Jth  even lucky number                            ║
  ║                   ║                                                    ║
  ║  j  k             ║  Jth  through  Kth (inclusive)       lucky numbers ║
  ║  j  k      lucky  ║  Jth  through  Kth (inclusive)       lucky numbers ║
  ║  j  k  evenLucky  ║  Jth  through  Kth (inclusive)  even lucky numbers ║
  ║                   ║                                                    ║
  ║  j -k             ║  all       lucky numbers in the range  j ──► |k|   ║
  ║  j -k      lucky  ║  all       lucky numbers in the range  j ──► |k|   ║
  ║  j -k  evenLucky  ║  all  even lucky numbers in the range  j ──► |k|   ║
  ╚═══════════════════╩════════════════════════════════════════════════════╝
                           where    |k|    is the absolute value of   k

Demonstrate the program by:

 showing the first twenty lucky numbers
 showing the first twenty even lucky numbers
 showing all lucky numbers between 6,000 and 6,100 (inclusive)
 showing all even lucky numbers in the same range as above
 showing the 10,000th lucky number (extra credit)
 showing the 10,000th even lucky number (extra credit)
See also

 This task is related to the Sieve of Eratosthenes task.
 OEIS Wiki Lucky numbers.
 Sequence A000959 lucky numbers on The On-Line Encyclopedia of Integer Sequences.
 Sequence A045954 even lucky numbers or ELN on The On-Line Encyclopedia of Integer Sequences.
 Entry lucky numbers on The Eric Weisstein's World of Mathematics.


with javascript_semantics
constant luckyMax = 120000
 
sequence lucky
 
procedure filterLucky()
    integer n = 2
    while n<=length(lucky) do
        integer m = lucky[n], 
                l = m-1
        for k=m+1 to length(lucky) do
            if mod(k,m)!=0 then
                l += 1
                lucky[l] = lucky[k]
            end if
        end for
        if l>=length(lucky) then exit end if
        lucky = lucky[1..l]
        n += 1
    end while
end procedure
 
constant helptxt = """
   argument(s)   |  what is displayed
=======================================
 j               |  jth lucky number
 j [,] lucky     |  jth lucky number
 j [,] evenLucky |  jth even lucky number
 j k             |  jth through kth (inclusive) lucky numbers
 j k lucky       |  jth through kth (inclusive) lucky numbers
 j k evenLucky   |  jth through kth (inclusive) even lucky numbers
 j -k            |  all lucky numbers in the range j to k
 j -k lucky      |  all lucky numbers in the range j to k
 j -k evenLucky  |  all even lucky numbers in the range j to k
"""
 
procedure fatal(string msg)
    puts(1,msg)
    puts(1,helptxt)
    {} = wait_key()
    abort(0)
end procedure

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

    lucky = tagset(luckyMax,2-oddluck,2)
    filterLucky()
    printf(1,"Output when args are %s\n",{join(cl)})
    string evenstr = iff(oddluck?"":"even ")
    if single then
        if j>length(lucky) then
            fatal(sprintf("the argument, %d, is too big", j))
        end if
        printf(1,"Lucky %snumber %d = %d\n",{evenstr,j, lucky[j]})
    elsif range then
        if k>length(lucky) then
            fatal(sprintf("the argument, %d, is too big", k))
        end if
        printf(1,"Lucky %snumbers %d to %d are: %v\n",{evenstr,j,k,lucky[j..k]})
    else
        if j>lucky[$] then
            fatal("start of range is too big")
        elsif k>lucky[$] then
            fatal("end of range is too big")
        end if
        integer m = abs(binary_search(j,lucky)),
                n = binary_search(k,lucky)
        if n<0 then n = -n-1 end if
        printf(1,"Lucky %snumbers between %d and %d are: %v\n", {evenstr,j,k,lucky[m..n]})
    end if
end procedure
 
procedure main()
    sequence cl = command_line()
    if length(cl)=2 then
--      fatal("at least one argument must be supplied") -- (if preferred)
        sequence tests = {"1 20",
                          "1 20 evenLucky",
                          "20 lucky",
                          "20 evenLucky",
                          "6000 -6100",
                          "6000 -6100 evenLucky",
                          "10000 lucky",
                          "10000 evenLucky"}
        -- (done this way to exercise the real command line handling...)
        if cl[1]=cl[2] then                     -- (compiled)
            cl = cl[1..1]
        elsif platform()=WINDOWS then           -- (and interpreted)
            cl[1] = substitute(cl[1],"pw","p")  -- (pw.exe -> p.exe)
        end if
        for i=1 to length(cl) do
            if find(' ',cl[i]) then cl[i] = sprintf("\"%s\"",{cl[i]}) end if
        end for
        for t=1 to length(tests) do
            if platform()=JS then
                -- (...except when we can't do that, of course)
                process(split(tests[t]))
            else
                string cmd = join(append(deep_copy(cl),tests[t]))
--              printf(1,"running %s\n",{cmd})
                {} = system_exec(cmd)
            end if
        end for
        puts(1, "tests complete\n") 
        {} = wait_key()
    else
        cl = cl[3..$] -- ({1,2} are {interperter,source} or {exe,exe})
        process(cl)
    end if
end procedure
main()
