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.


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