Lucky and even lucky numbers: Difference between revisions
Content added Content deleted
m (→{{header|Wren}}: Wren-trait -> Wren-iterate) |
|||
Line 1,430: | Line 1,430: | ||
Result: 111842 |
Result: 111842 |
||
</pre> |
</pre> |
||
=={{header|jq}}== |
|||
'''Works with jq and jaq, the C and Rust implementions of jq''' |
|||
Also works with gojq, the Go implementation, but gojq requires |
|||
a very large amount of memory to complete the last task (finding the 10,000th even lucky number). |
|||
The following program has been written to run using the C, Go and Rust |
|||
implementations of jq and is therefore not as succinct as it would |
|||
otherwise have been. Also, the mechanisms for passing in command-line |
|||
parameters differ amongst the three implementations, so the program presented here expects the |
|||
parameters to be presented on a single line as input. Thus a possible |
|||
invocation would be: |
|||
<pre> |
|||
JQ -Rrcf program.jq <<< '1 20' |
|||
</pre> |
|||
The disadvantage of the sieve-based approach used below is the |
|||
difficulty of choosing a sieve size that is on the one hand sufficient |
|||
but on the other frugal. No claim is made for the algorithm used to |
|||
determine the sieve size here other than it is reasonable for problems |
|||
sufficiently similar to the ones solved here. However, if the sieve size |
|||
turns out to be insufficient, an error condition will be raised. |
|||
<syntaxhighlight lang=jq> |
|||
# Preliminaries: |
|||
# This def can be omitted if using jq or gojq: |
|||
def range($a;$b;$c): $a | while(. < $b; .+$c); |
|||
# jaq does not support string interpolation so, for brevity: |
|||
def tos: tostring; |
|||
# The following def should be modified if an alternative mechanism for |
|||
# reading the parameter arguments is used: |
|||
def args: {args: [splits(" *")]}; |
|||
def argsSize: .args|length; |
|||
# Input: an array |
|||
# Emit the items in the array until the condition on the items is met. |
|||
# The item for which the condition is first met is NOT emitted. |
|||
def emit_until(cond): |
|||
length as $length |
|||
| if $length == 0 or (.[0]|cond) then empty |
|||
else . as $in |
|||
| {i:0, ok: true} |
|||
| while(.ok; |
|||
.i+=1 |
|||
| .ok = .i < $length and ($in[.i] | cond | not) ) |
|||
| $in[.i] |
|||
end; |
|||
# input: a number or a string |
|||
# If the input is or can be converted to a number using tonumber, then return the number |
|||
# else return false. |
|||
def isnumber: |
|||
if type == "number" then . |
|||
elif type == "string" then tonumber? // false |
|||
else false |
|||
end; |
|||
# input: anything |
|||
# output: a boolean |
|||
def isinteger: |
|||
if type == "number" then . == floor |
|||
else isnumber as $x |
|||
| if $x then $x | (. == floor) else false end |
|||
end; |
|||
# mark and collapse |
|||
def removeEvery($n): |
|||
reduce range($n-1; length; $n) as $i (.; .[$i]=null) |
|||
| map(select(.)); |
|||
# Input: {lucky} |
|||
def filterLucky: |
|||
(.lucky|length) as $length |
|||
| .n = 2 |
|||
| until( .n >= $length; |
|||
.lucky[.n-1] as $m |
|||
| if $m then .lucky |= removeEvery($m) | .n += 1 |
|||
else .n = $length |
|||
end ) |
|||
| del(.n); |
|||
def printSingle($j): |
|||
if $j >= 1 + (.lucky|length) then "Argument is too big" | error |
|||
else |
|||
(if .odd then "Lucky number #" else "Lucky even number #" end) |
|||
+ ($j|tos) + " = " + (.lucky[$j-1]|tos) |
|||
end; |
|||
# like jq's range($j-1; $k) |
|||
def printRange($j; $k): |
|||
if $k >= (.lucky|length) then "Argument " + ($k|tos) + " is too big" | error |
|||
elif .odd |
|||
then "Lucky numbers " + ($j|tos) + " to " + ($k|tos) + " inclusive are:", |
|||
.lucky[$j-1:$k] |
|||
else "Lucky even numbers " + ($j|tos) + " to " + ($k|tos) + " inclusive are:", |
|||
.lucky[$j-1:$k] |
|||
end; |
|||
def printBetween($j; $k): |
|||
.lucky[-1] as $max |
|||
| if $j > $max or $k > $max |
|||
then "At least one argument is too big" | error |
|||
else |
|||
(if .odd |
|||
then "Lucky numbers between " + ($j|tos) + " and " + ($k|tos) + " are:" |
|||
else "Lucky even numbers between " + ($j|tos) + " and " + ($k|tos) + " are:" |
|||
end), |
|||
[.lucky | emit_until(. > $k) | select(. >= $j)] |
|||
end; |
|||
def odd: |
|||
if argsSize < 3 then true |
|||
else (.args[2] | tostring | ascii_downcase) |
|||
| if . == "lucky" or . == "odd" then true |
|||
elif . == "evenlucky" or . == "even" then false |
|||
else "Third argument " + (.args[2]|tos) + " is invalid" | error |
|||
end |
|||
end; |
|||
# Input: {odd} |
|||
def init($n): |
|||
if .odd |
|||
then .lucky = reduce range(0;$n) as $i (null; . + [$i*2 + 1]) |
|||
else .lucky = reduce range(0;$n) as $i (null; . + [$i*2 + 2]) |
|||
end; |
|||
# Emit {args, j, k, odd, single} or raise an error |
|||
def gatherArgs: |
|||
args |
|||
| if argsSize | (. < 1 or . > 3) |
|||
then "There must be between 1 and 3 command line arguments" | error |
|||
else .j = (.args[0] | isnumber ) |
|||
| .k = (.args[1] | isnumber ) |
|||
| .single = (argsSize == 1 or .args[1] == ",") |
|||
| .odd = odd |
|||
| if (.j | isinteger | not) or (.j < 1) |
|||
then "First argument " + (.args[0]|tos) + " must be a positive integer" | error |
|||
elif argsSize >= 2 and .args[1] != "," and (.k | isinteger | not) |
|||
then "Second argument " + (.args[1]|tos) + " must be an integer or ," | error |
|||
else . |
|||
end |
|||
| if .k and .k >= 0 and .j > .k |
|||
then "Second argument cannot be less than first" | error |
|||
else . |
|||
end |
|||
end ; |
|||
def start: |
|||
gatherArgs |
|||
| (if .k then (if .k > 0 then .k else null end) else .j end) as $size |
|||
| (if $size then ($size | . * (tostring|length|.*.)) else -.k end) as $size |
|||
| init($size|debug) |
|||
| filterLucky |
|||
| if .single then printSingle(.j) |
|||
elif .k > 0 then printRange(.j; .k) |
|||
else .k |= - . |
|||
| if (.j > .k) |
|||
then "The second argument cannot be less in absolute value than first" | error |
|||
else printBetween(.j; .k) |
|||
end |
|||
end; |
|||
start |
|||
</syntaxhighlight> |
|||
{{output}} |
|||
<pre> |
|||
Lucky numbers 1 to 20 inclusive are: |
|||
[1,3,7,9,13,15,21,25,31,33,37,43,49,51,63,67,69,73,75,79] |
|||
Lucky even numbers 1 to 20 inclusive are: |
|||
[2,4,6,10,12,18,20,22,26,34,36,42,44,50,52,54,58,68,70,76] |
|||
Lucky numbers between 6000 and 6100 are: |
|||
[6009,6019,6031,6049,6055,6061,6079,6093] |
|||
Lucky even numbers between 6000 and 6100 are: |
|||
[6018,6020,6022,6026,6036,6038,6050,6058,6074,6090,6092] |
|||
Lucky number #1000 = 8809 |
|||
Lucky even number #10000 = 111842 |
|||
</pre> |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |