Add sumDivisors and peterson implementation
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
open System
|
||||
|
||||
let factorsWithMolteplicity n =
|
||||
let rec loop c p =
|
||||
if c < (p * p) then [c]
|
||||
elif c % p = 0 then p :: (loop (c/p) p)
|
||||
else loop c (p + 1)
|
||||
loop n 2
|
||||
|> List.countBy id
|
||||
|
||||
let isPerfect n =
|
||||
let sumDiv k =
|
||||
k
|
||||
|> factorsWithMolteplicity
|
||||
|> List.map (fun (p,m) -> ((pown p (m+1))-1)/(p-1))
|
||||
|> List.fold (*) 1
|
||||
sumDiv n = 2*n
|
||||
|
||||
// brute-force approach
|
||||
let divisors n =
|
||||
[1..n/2]
|
||||
|> Seq.filter (fun f -> n % f = 0)
|
||||
let sumProperDivisors n =
|
||||
n
|
||||
|> divisors
|
||||
|> Seq.sum
|
||||
|
||||
// perfect
|
||||
let isPerfect2 n = (sumProperDivisors n = n)
|
||||
|
||||
let timer = new System.Diagnostics.Stopwatch()
|
||||
timer.Start()
|
||||
printfn "%A" (isPerfect 8128)
|
||||
timer.Stop()
|
||||
printfn "%f" timer.Elapsed.TotalMilliseconds
|
||||
printfn "Elapsed Time: %i" timer.ElapsedMilliseconds
|
||||
|
||||
let timer2 = new System.Diagnostics.Stopwatch()
|
||||
timer2.Start()
|
||||
printfn "%A" (isPerfect2 8128)
|
||||
timer2.Stop()
|
||||
printfn "%f" timer2.Elapsed.TotalMilliseconds
|
||||
printfn "Elapsed Time: %i" timer2.ElapsedMilliseconds
|
||||
@@ -0,0 +1,24 @@
|
||||
N=1e7;
|
||||
|
||||
for n=2:N
|
||||
% A contains the unique prime factors of n; M their multiplicities
|
||||
[A,M]=factor(n);
|
||||
l=length(A);
|
||||
s=1;
|
||||
for i=1:l
|
||||
% formula for the sum of divisors of p^k
|
||||
c(i)=((A(i)^(M(i)+1))-1)/(A(i)-1);
|
||||
s*=c(i);
|
||||
end
|
||||
if 2*n==s
|
||||
printf("%d is Perfect!\n",n)
|
||||
m=n;
|
||||
k=0;
|
||||
while mod(m,2)==0
|
||||
m=m/2;
|
||||
k++;
|
||||
end
|
||||
k++;
|
||||
printf("The corresponding Mersenne prime is %d\n",((2^k)-1))
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user