Very nice solution. I wonder if the unique once vs. every loop isn’t a gain because divs generally doesn’t grow that large, even when there are duplicates.

–Loren

]]>A nice trick for finding the list of all divisors of an integer that is more efficient than the symengine solution is to use kron.

n = 10581480;

n has a lot of divisors, including 17, a very interesting number for some of us, and 1729, a number that others consider even more interesting. Including n itself, there are 384 distinct integer divisors. It takes a bit to compute the list of all divisors.

tic,double(feval(symengine,’numlib::divisors’, n));toc

Elapsed time is 0.024904 seconds.

Here is a simple solution in MATLAB.

tic

divs = 1;

for f = factor(n)

divs = unique(kron(divs,[1,f]));

end

toc

Elapsed time is 0.004309 seconds.

Interestingly, avoiding the multiple calls to unique is not hard, but it does not seem to save any time.

tic

f = factor(n);

k = [0,find(diff(f)),numel(f)];

divs = 1;

for i = 2:numel(k)

divs = kron(divs,f(k(i)).^(0:(k(i) – k(i-1))));

end

toc

Elapsed time is 0.005534 seconds.

Either case is faster than the symbolic solution though.

John

]]>factor2(28) ans = 1 2 4 7 14 28 So: trimFactors = @(x) x(1:end-1); isperfect = @(x) sum(trimFactors(factor2(x)))==x; isperfect(5) isperfect(6) isperfect(28) ans = 0 ans = 1 ans = 1

Cheers!

Brett