Jump to content

Zumkeller numbers: Difference between revisions

m
→‎{{header|AppleScript}}: Incorporated "abundant number" optimisation for odd numbers.
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:
 
=={{header|AppleScript}}==
On my machine, this takes about 0.3528 seconds to perform the two main searches and a further 109107 to do the stretch task. However, the latter time can be dramatically reduced to 1.877 seconds with the cheat of foreknowingknowing beforehand that at least 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>-- ReturnSum n's proper divisors.
on aliquotSum(n)
if ((halfSum < n) or (halfSum < sum / 2)) then return false0
set sum to n1
set halfSumsqrt to sumn div^ 20.5
set limit to sqrt div 1
if (limit = sqrt) then
set sum to sum + limit
set limit to limit - 1
end scriptif
repeat with thisDivisori infrom o's2 divisorsto limit
if (n mod i is 0) then set sum to sum + i + n div i
end repeat
return sum
end aliquotSum
 
-- Return n's proper divisors.
on properDivisors(n)
set output to {}
Line 599 ⟶ 616:
-- Is n a Zumkeller number?
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 Getor n'sa subset of its proper divisors. nsums itselfto isn'tthe neededaverage orof wantedit inand thisall listits 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.
end script
-- 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.
set sum to n
tell aliquotSum(n) to ¬
repeat with thisDivisor in o's divisors
setreturn sum((it to sumn) +and thisDivisor((it - n) mod 2 = 0) and ¬
((n mod 2 = 1) or (my subsetSumsTo(my properDivisors(n), (it + n) div 2))))
end repeat
set halfSum to sum div 2
-- If the result's large enough, accurate, and summable to from a subset of the divisors, n's a Zumkeller.
if ((halfSum < n) or (halfSum < sum / 2)) then return false
return ((halfSum = n) or (subsetSumsTo(o's divisors, halfSum)))
end isZumkeller
 
Line 681 ⟶ 693:
end script
if (cheating) then
-- Knowing that the HCF of at least the first 200 odd Zumkellers notwhich don't endingend with 5
-- are divisible byis 63, only check 63 and each 126th number, starting with 63 itselfthereafter.
-- (Somewhere between 200 and 500, the HCF reduces to 21, so adjust accordingly.)
set zumkellers to zumkellerNumbers(40, 63, 126, no5Multiples)
else
557

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.