Lucky and even lucky numbers
definition of lucky numbers
Lucky numbers are positive integers that are formed by:
- take a list of all the positive integers
- remove every 2nd number
- take the 2nd number (which is 3 )
- remove every 3rd number
- take the 3rd number (which is 7 )
- remove every 7th number
- take the 4th number (which is 9 )
- remove every 9th number
- take the 5th number (which is 13 )
- remove every 13th number
- take the 6th number ···
definition of even lucky numbers
Even lucky numbers are positive even integers that are formed by:
- take a list of all the positive even integers
- remove every 2nd number
- take the 2nd number (which is 4 )
- remove every 4th number
- take the 3rd number (which is 6 )
- remove every 6th number
- take the 4th number (which is 10 )
- remove every 10th number
- take the 5th number (which is 12 )
- remove every 12th number
- take the 6th number ···
task requirements
- write one or two subroutines (functions) to generate lucky numbers and even lucky numbers
- which kind of numbers and which number(s) will be specified via the command line or a similar interface.
- 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)
- mixed case should be supported
- support for a particular number
- support for a range of particular numbers
- support for a range of values
The program should support the arguments:
what is displayed (on a single line) argument(s) (optional verbage 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
Specifically:
- show the first twenty lucky numbers
- show the first twenty even lucky numbers
- show all lucky numbers between 6,000 and 6,100 (inclusive)
- show all even lucky numbers in the same range as above
- show the 10,000th lucky number (extra credit)
- show the 10,000th even lucky number (extra credit)
see also
- This task is related to the Sieve of Eratosthenes task.
- 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.
- Wiki entry lucky_number.
Perl 6
<lang perl6>sub luck(\a,\b) {
gather {
my @taken = take a; my @rotor; my $i = b;
loop { loop (my $j = 0; $j < @rotor; $j++) { --@rotor[$j] or last; } if $j < @rotor { @rotor[$j] = @taken[$j+1]; } else { push @taken, take $i; push @rotor, $i - @taken; } $i += 2; }
}
}
constant @lucky = luck(1,3); constant @evenlucky = luck(2,4);
subset Luck where m:i/^ 'even'? 'lucky' $/;
multi MAIN (Int $num where * > 0) {
say @lucky[$num-1];
}
multi MAIN (Int $num where * > 0, ',', Luck $howlucky = 'lucky') {
say @::(lc $howlucky)[$num-1];
}
multi MAIN (Int $first where * > 0, Int $last where * > 0, Luck $howlucky = 'lucky') {
say @::(lc $howlucky)[$first-1 .. $last - 1];
}
multi MAIN (Int $min where * > 0, Int $neg-max where * < 0, Luck $howlucky = 'lucky') {
say grep * >= $min, (@::(lc $howlucky) ...^ * > abs $neg-max);
}</lang>
- Output:
$ ./lucky Usage: ./lucky <num> ./lucky <num> , [<howlucky>] ./lucky <first> <last> [<howlucky>] ./lucky <min> <neg-max> [<howlucky>] $ ./lucky 20 lucky 79 $ ./lucky 20 evenlucky 76 $ ./lucky 1 20 1 3 7 9 13 15 21 25 31 33 37 43 49 51 63 67 69 73 75 79 $ ./lucky 1 20 evenlucky 2 4 6 10 12 18 20 22 26 34 36 42 44 50 52 54 58 68 70 76 $ ./lucky 6000 -6100 6009 6019 6031 6049 6055 6061 6079 6093 $ ./lucky 6000 -6100 evenLucky 6018 6020 6022 6026 6036 6038 6050 6058 6074 6090 6092 $ ./lucky 10000 115591 $ ./lucky 10000 EVENLUCKY 111842
Python
The generator <lang python>from __future__ import print_function from itertools import islice import sys, re
class ArgumentError(Exception):
pass
def lgen(even=False, nmax=1000000):
start = 2 if even else 1 n, lst = 1, list(range(start, nmax + 1, 2)) lenlst = len(lst) yield lst[0] while n < lenlst and lst[n] < lenlst: yield lst[n] n, lst = n + 1, [j for i,j in enumerate(lst, 1) if i % lst[n]] lenlst = len(lst) # drain for i in lst[n:]: yield i</lang>
The argument handler <lang python>def arghandler(argstring):
match_obj = re.match( r"""(?mx) (?: (?P<SINGLE> (?: ^ (?P<SINGLEL> \d+ ) (?: | \s , \s lucky ) \s* $ ) |(?: ^ (?P<SINGLEE> \d+ ) (?: | \s , \s evenLucky ) \s* $ ) ) |(?P<KTH> (?: ^ (?P<KTHL> \d+ \s \d+ ) (?: | \s lucky ) \s* $ ) |(?: ^ (?P<KTHE> \d+ \s \d+ ) (?: | \s evenLucky ) \s* $ ) ) |(?P<RANGE> (?: ^ (?P<RANGEL> \d+ \s -\d+ ) (?: | \s lucky ) \s* $ ) |(?: ^ (?P<RANGEE> \d+ \s -\d+ ) (?: | \s evenLucky ) \s* $ ) ) )""", argstring) if match_obj: # Retrieve group(s) by name SINGLEL = match_obj.group('SINGLEL') SINGLEE = match_obj.group('SINGLEE') KTHL = match_obj.group('KTHL') KTHE = match_obj.group('KTHE') RANGEL = match_obj.group('RANGEL') RANGEE = match_obj.group('RANGEE') if SINGLEL: j = int(SINGLEL) assert 0 < j < 10001, "Argument out of range" print("Single %i'th lucky number:" % j, end=' ') print( list(islice(lgen(), j-1, j))[0] ) elif SINGLEE: j = int(SINGLEE) assert 0 < j < 10001, "Argument out of range" print("Single %i'th even lucky number:" % j, end=' ') print( list(islice(lgen(even=True), j-1, j))[0] ) elif KTHL: j, k = [int(num) for num in KTHL.split()] assert 0 < j < 10001, "first argument out of range" assert 0 < k < 10001 and k > j, "second argument out of range" print("List of %i ... %i lucky numbers:" % (j, k), end=' ') for n, luck in enumerate(lgen(), 1): if n > k: break if n >=j: print(luck, end = ', ') print() elif KTHE: j, k = [int(num) for num in KTHE.split()] assert 0 < j < 10001, "first argument out of range" assert 0 < k < 10001 and k > j, "second argument out of range" print("List of %i ... %i even lucky numbers:" % (j, k), end=' ') for n, luck in enumerate(lgen(even=True), 1): if n > k: break if n >=j: print(luck, end = ', ') print() elif RANGEL: j, k = [int(num) for num in RANGEL.split()] assert 0 < j < 10001, "first argument out of range" assert 0 < -k < 10001 and -k > j, "second argument out of range" k = -k print("List of lucky numbers in the range %i ... %i :" % (j, k), end=' ') for n in lgen(): if n > k: break if n >=j: print(n, end = ', ') print() elif RANGEE: j, k = [int(num) for num in RANGEE.split()] assert 0 < j < 10001, "first argument out of range" assert 0 < -k < 10001 and -k > j, "second argument out of range" k = -k print("List of even lucky numbers in the range %i ... %i :" % (j, k), end=' ') for n in lgen(even=True): if n > k: break if n >=j: print(n, end = ', ') print() else: raise ArgumentError( Error Parsing Arguments! Expected Arguments of the form (where j and k are integers): 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| )
if __name__ == '__main__':
arghandler(' '.join(sys.argv[1:]))</lang>
- Output:
# Output when arguments are: 1 20 lucky List of 1 ... 20 lucky numbers: 1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 49, 51, 63, 67, 69, 73, 75, 79, # Output when arguments are: 1 20 evenLucky List of 1 ... 20 even lucky numbers: 2, 4, 6, 10, 12, 18, 20, 22, 26, 34, 36, 42, 44, 50, 52, 54, 58, 68, 70, 76, # Output when arguments are: 6000 -6100 lucky List of lucky numbers in the range 6000 ... 6100 : 6009, 6019, 6031, 6049, 6055, 6061, 6079, 6093, # Output when arguments are: 6000 -6100 evenLucky List of even lucky numbers in the range 6000 ... 6100 : 6018, 6020, 6022, 6026, 6036, 6038, 6050, 6058, 6074, 6090, 6092, # Output when arguments are: 10000 Single 10000'th lucky number: 115591 # Output when arguments are: 10000 , evenLucky Single 10000'th even lucky number: 111842
REXX
<lang REXX>/*REXX program displays lucky or evenLucky integers (#'s or a # range).*/ parse arg bot top func _ . /*get what we need from the C.L. */ if func== then func='lucky' /*Not defined? Use the default. */ s=left('s',bot\==top & top\==",") /*plural results (or not plural).*/ say func 'number's":" bot top '───►' $lucky(bot, top, func, _) exit /*stick a fork in it, we're done.*/ /*────────────────────────────────$LUCKY subroutine─────────────────────*/ $lucky: arg x,y,f,?; if y== | y==',' then y=x /*get some vars.*/
- =0; $=; ny=y<0 /*set variable: NOY: value range*/
if f== then f='LUCKY'; lucky=f=='LUCKY' /*assume LUCKY if omitted*/ if f\=='LUCKY' & f\=='EVENLUCKY' then return 'function not valid: ' f if arg()>3 & ?\= then return "too many arguments entered: " ? if x= then return "1st argument is missing." if x<1 then return "1st argument isn't a positive integer: " x if \datatype(x,'W') then return "1st argument isn't an integer: " x if \datatype(y,'W') then return "2nd argument isn't an integer: " y if x>ay then return "2nd arg is less than 1st arg." ay=abs(y); yL=ay; if y>0 then yL=y*10+y+y /*adjust the upper Y limit. */ if f== then f='LUCKY'; lucky=f=='LUCKY'
/* [↓] build for LUCKY|EVENLUCKY*/ do j=1 until j>=yL /*construct list of pos integers.*/ if j//2==(\lucky) then iterate /*EVENLUCKY? Use only even ints.*/
if lucky then if (j+1)//6==0 then iterate /*prune if mod 6≡zero.*/ else nop /*balance the IF logic. */ else if j //8==0 then iterate /*prune next if mod 8≡0.*/ #=#+1 /*bump the counter of #'s found. */ $=$ j /*append integer to the $ list.*/ end /*j*/
z=0
do p=3 until z==; z=word($,p) /*start to prune the integer list*/ if z># then leave /*if integer is too large, stop. */ do j=#%z*z by -z to z /*elide every Zth int.*/ $=delword($,j,1) /*delete a particular #.*/ #=#-1 /*decrease integer count*/ end /*j*/ /*delete from right end.*/ end /*p*/
@.=
do k=1; parse var $ q $; if q== then leave; @.k=q; end /*k*/
@.0=k-1
do j=1 for # /*restrict the found integers. */ if (\ny & (j<x | j>ay)) | (ny & (@.j<x | @.j>ay)) then @.j= end /*j*/ /* [↑] a list of #s or a range. */
_=
do b=1 for @.0; _=_ @.b; end /*build a list. */
return space(_) /*remove superfluous list blanks.*/</lang> output when the input is: 1 20 lucky
lucky numbers: 1 20 ───► 1 3 7 9 13 15 21 25 31 33 37 43 49 51 63 67 69 73 75 79
output when the input is: 1 20 evenLucky
evenLucky numbers: 1 20 ───► 2 4 6 10 12 18 20 22 26 34 36 42 44 50 52 54 58 68 70 76
output when the input is: 6000 -6100 lucky
lucky numbers: 6000 -6100 ───► 6009 6019 6031 6049 6055 6061 6079 6093
output when the input is: 6000 -6100 evenLucky
evenLucky numbers: 6000 -6100 ───► 6018 6020 6022 6026 6036 6038 6050 6058 6074 6090 6092
output when the input is: 10000
lucky number: 10000 ───► 115591
output when the input is: 10000 , evenLucky
evenLucky number: 10000 ───► 111842