Zumkeller numbers: Difference between revisions
Content added Content deleted
m (→{{header|AppleScript}}: Minor tweaks, comment and label changes, optional cheat to reduce the stretch goal time.) |
m (→{{header|AppleScript}}: Incorporated "abundant number" optimisation for odd numbers.) |
||
Line 550: | Line 550: | ||
=={{header|AppleScript}}== |
=={{header|AppleScript}}== |
||
On my machine, this takes about 0. |
On my machine, this takes about 0.28 seconds to perform the two main searches and a further 107 to do the stretch task. However, the latter time can be dramatically reduced to 1.7 seconds with the cheat of knowing beforehand that the first 200 or so odd Zumkellers not ending with 5 are divisible by 63. The "abundant number" optimisation's now used with odd numbers, but the cheat-free running time was only two to three seconds longer without it. |
||
<lang applescript>-- |
<lang applescript>-- Sum n's proper divisors. |
||
on aliquotSum(n) |
|||
⚫ | |||
⚫ | |||
⚫ | |||
set limit to sqrt div 1 |
|||
if (limit = sqrt) then |
|||
set sum to sum + limit |
|||
set limit to limit - 1 |
|||
⚫ | |||
⚫ | |||
if (n mod i is 0) then set sum to sum + i + n div i |
|||
⚫ | |||
⚫ | |||
return sum |
|||
end aliquotSum |
|||
-- Return n's proper divisors. |
|||
on properDivisors(n) |
on properDivisors(n) |
||
set output to {} |
set output to {} |
||
Line 599: | Line 616: | ||
-- Is n a Zumkeller number? |
-- Is n a Zumkeller number? |
||
on isZumkeller(n) |
on isZumkeller(n) |
||
-- Yes if its aliquot sum is greater than or equal to it, the difference between them is even, and |
|||
script o |
|||
-- either n is odd or a subset of its proper divisors sums to the average of it and all its proper divisors. |
|||
-- The 'or equal' logic works because (below 2,000,000 at least) no odd numbers, and only the even |
|||
property divisors : properDivisors(n) |
|||
-- Zumkellers 6, 28, 496, and 8128, /are/ equal to their aliquot sums. The rest are all greater or smaller. |
|||
⚫ | |||
-- Using the aliquotSum() handler not only saves creating and looping through a list of the proper divisors |
|||
⚫ | |||
-- when n is odd, but the result also eliminates enough evens that calling properDivisors() on top of that |
|||
-- Sum all the divisors (including n) and halve the result, rounding towards zero. |
|||
-- to handle what's left is still faster than using properDivisors() with all the even numbers. |
|||
⚫ | |||
tell aliquotSum(n) to ¬ |
|||
⚫ | |||
return ((it ≥ n) and ((it - n) mod 2 = 0) and ¬ |
|||
((n mod 2 = 1) or (my subsetSumsTo(my properDivisors(n), (it + n) div 2)))) |
|||
⚫ | |||
⚫ | |||
-- If the result's large enough, accurate, and summable to from a subset of the divisors, n's a Zumkeller. |
|||
⚫ | |||
return ((halfSum = n) or (subsetSumsTo(o's divisors, halfSum))) |
|||
end isZumkeller |
end isZumkeller |
||
Line 681: | Line 693: | ||
end script |
end script |
||
if (cheating) then |
if (cheating) then |
||
-- Knowing that at least the first 200 odd Zumkellers |
-- Knowing that the HCF of at least the first 200 odd Zumkellers which don't end with 5 |
||
-- |
-- is 63, only check 63 and each 126th number thereafter. |
||
-- (Somewhere between 200 and 500, the HCF reduces to 21, so adjust accordingly.) |
|||
set zumkellers to zumkellerNumbers(40, 63, 126, no5Multiples) |
set zumkellers to zumkellerNumbers(40, 63, 126, no5Multiples) |
||
else |
else |