Hello,

I started with Julia last week and to get into tracks I tried to implement
some of the Project Euler question, that I've already done in Mathematica.

The specifics of this question is about problem #21:

Let d(*n*) be defined as the sum of proper divisors of *n* (numbers less 
than *n* which divide evenly into *n*).
If d(*a*) = *b* and d(*b*) = *a*, where *a* [image: ≠] *b*, then *a* and *b* 
are 
an amicable pair and each of *a* and *b* are called amicable numbers.

For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 
55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 
71 and 142; so d(284) = 220.

Evaluate the sum of all the amicable numbers under 10000.


In Mathematica this was done very easily with:

DivSum[n_] := DivisorSigma[1, n] - n
AmicableQ[n_Integer] := DivSum[n] != n && DivSum[DivSum[n]] == n
Plus @@ Select[Range[9999], AmicableQ] // Timing


Yielding a tuple of time and the result: {0.178553, 31626}

Which is correct. So I tried to achieve the same in Julia:

 function divisors(n::Int, prop::Bool=false)
    if(!prop)
        filter((x) -> rem(n, x) == 0, [1:n])
    else
        filter((x) -> rem(n, x) == 0, [1:n-1])
    end
end

 

function divsum(n::Int)
    sum(divisors(n, true))
end

 

function amicable(n::Int)
    divsum(n) != n && divsum(divsum(n)) == n
end

 

This yielded the correct result, but awful timing:

@time sum(filter(x -> amicable(x),[1:9999]))


elapsed time: 24.025008574 seconds (4310013792 bytes allocated) 


So. I did something wrong, apparently. Rats.

So I started to think about, where the hot spot was and
decided to pick the divisors function to be the suspect.

So I rewrote it:

function factors(n)
    f = [one(n)]
    for (p,e) in factor(n)
        f = reduce(vcat, f, [f*p^j for j in 1:e])
    end
    return f
end

 

function sum_prop_factors(n)
    sum(factors(n))-n
end

 

I did even left out the sorting before return f back, since it isn't needed 
at all.

Executing this:

@time sum(filter(x -> sum_prop_factors(x) != x && 
sum_prop_factors(sum_prop_factors(x))==x, [2:9999]))


yielded:

elapsed time: 0.207550349 seconds (39478048 bytes allocated) 

 

Reply via email to