Duffinian numbers: Difference between revisions
Content added Content deleted
(Added Quackery.) |
|||
Line 538: | Line 538: | ||
6399 6400 6401 |
6399 6400 6401 |
||
8449 8450 8451</syntaxhighlight> |
8449 8450 8451</syntaxhighlight> |
||
=={{header|jq}}== |
|||
{{works with|jq}} |
|||
The solution presented here follows the Wren and similar entries on this page |
|||
in hard-coding the size of the prime sieve used to produce the answer; |
|||
while this approach helps speed things up, it does assume some foreknowledge. |
|||
'''Preliminaries''' |
|||
<syntaxhighlight lang=jq> |
|||
def count(s): reduce s as $x (0; .+1); |
|||
def isSquare: |
|||
(sqrt|floor) as $sqrt |
|||
| . == ($sqrt | .*.); |
|||
# return an array, $a, of length . or slightly greater, such that |
|||
# $a[$i] is $i if $i is prime, and false otherwise. |
|||
def primeSieve: |
|||
# erase(i) sets .[i*j] to false for integral j > 1 |
|||
def erase(i): |
|||
if .[i] then |
|||
reduce range(2; (1 + length) / i) as $j (.; .[i * $j] = false) |
|||
else . |
|||
end; |
|||
(. + 1) as $n |
|||
| (($n|sqrt) / 2) as $s |
|||
| [null, null, range(2; $n)] |
|||
| reduce (2, 1 + (2 * range(1; $s))) as $i (.; erase($i)); |
|||
def gcd(a; b): |
|||
# subfunction expects [a,b] as input |
|||
# i.e. a ~ .[0] and b ~ .[1] |
|||
def rgcd: if .[1] == 0 then .[0] |
|||
else [.[1], .[0] % .[1]] | rgcd |
|||
end; |
|||
[a,b] | rgcd; |
|||
# divisors as an unsorted stream (without calling sqrt) |
|||
def divisors: |
|||
if . == 1 then 1 |
|||
else . as $n |
|||
| label $out |
|||
| range(1; $n) as $i |
|||
| ($i * $i) as $i2 |
|||
| if $i2 > $n then break $out |
|||
else if $i2 == $n |
|||
then $i |
|||
elif ($n % $i) == 0 |
|||
then $i, ($n/$i) |
|||
else empty |
|||
end |
|||
end |
|||
end; |
|||
</syntaxhighlight> |
|||
'''The Task''' |
|||
<syntaxhighlight lang=jq> |
|||
# emit an array such that .[i] is i if i is Duffinian and false otherwise |
|||
def duffinianArray($limit): |
|||
($limit | primeSieve | map(not)) |
|||
| .[1] = false |
|||
| reduce range(2; $limit) as $i (.; |
|||
if (.[$i]|not) then . |
|||
else if ($i % 2) == 0 and ($i|isSquare|not) and (($i/2)|isSquare|not) |
|||
then .[$i] = false |
|||
else sum($i|divisors) as $sigmaSum |
|||
| if gcd($sigmaSum; $i) != 1 |
|||
then .[$i] = false |
|||
else . |
|||
end |
|||
end |
|||
end ); |
|||
# Input: duffinianArray($limit) |
|||
# Output: an array of the corresponding Duffinians |
|||
def duffinians: |
|||
. as $d |
|||
| reduce range(1;length) as $i ([]; if $d[$i] then . + [$i] else . end); |
|||
# Input: duffinians |
|||
# Output: stream of triplets |
|||
def triplets: |
|||
. as $d |
|||
| range (2; length) as $i |
|||
| select( $d[$i] and $d[$i-1] and $d[$i-2] ) |
|||
| [$i-2, $i-1, $i]; |
|||
def withCount(s; $msg): |
|||
foreach (s,null) as $x (0; .+1; |
|||
if $x == null then "\($msg) \(.-1)" else $x end ); |
|||
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .; |
|||
# 167039 is the minimum integer that is sufficient to produce 50 triplets |
|||
duffinianArray(167039) |
|||
| "First 50 Duffinian numbers:", |
|||
(duffinians[0:50] | _nwise(10) | map(lpad(4)) | join(" ") ), |
|||
"\nFirst 50 Duffinian triplets:", |
|||
withCount(limit(50;triplets); "\nNumber of triplets: ") |
|||
</syntaxhighlight> |
|||
{{output}} |
|||
<pre> |
|||
First 50 Duffinian numbers: |
|||
4 8 9 16 21 25 27 32 35 36 |
|||
39 49 50 55 57 63 64 65 75 77 |
|||
81 85 93 98 100 111 115 119 121 125 |
|||
128 129 133 143 144 155 161 169 171 175 |
|||
183 185 187 189 201 203 205 209 215 217 |
|||
First 50 Duffinian triplets: |
|||
[63,64,65] |
|||
[323,324,325] |
|||
[511,512,513] |
|||
[721,722,723] |
|||
[899,900,901] |
|||
[1443,1444,1445] |
|||
[2303,2304,2305] |
|||
[2449,2450,2451] |
|||
[3599,3600,3601] |
|||
[3871,3872,3873] |
|||
[5183,5184,5185] |
|||
[5617,5618,5619] |
|||
[6049,6050,6051] |
|||
[6399,6400,6401] |
|||
[8449,8450,8451] |
|||
[10081,10082,10083] |
|||
[10403,10404,10405] |
|||
[11663,11664,11665] |
|||
[12481,12482,12483] |
|||
[13447,13448,13449] |
|||
[13777,13778,13779] |
|||
[15841,15842,15843] |
|||
[17423,17424,17425] |
|||
[19043,19044,19045] |
|||
[26911,26912,26913] |
|||
[30275,30276,30277] |
|||
[36863,36864,36865] |
|||
[42631,42632,42633] |
|||
[46655,46656,46657] |
|||
[47523,47524,47525] |
|||
[53137,53138,53139] |
|||
[58563,58564,58565] |
|||
[72961,72962,72963] |
|||
[76175,76176,76177] |
|||
[79523,79524,79525] |
|||
[84099,84100,84101] |
|||
[86527,86528,86529] |
|||
[94177,94178,94179] |
|||
[108899,108900,108901] |
|||
[121103,121104,121105] |
|||
[125315,125316,125317] |
|||
[128017,128018,128019] |
|||
[129599,129600,129601] |
|||
[137287,137288,137289] |
|||
[144399,144400,144401] |
|||
[144721,144722,144723] |
|||
[154567,154568,154569] |
|||
[158403,158404,158405] |
|||
[166463,166464,166465] |
|||
[167041,167042,167043] |
|||
Number of triplets: 50 |
|||
</pre> |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |