Perfect numbers: Difference between revisions
m
syntax highlighting fixup automation
No edit summary |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 27:
{{trans|Python}}
<
V sum = 0
L(i) 1 .< n
Line 36:
L(i) 1..10000
I perf(i)
print(i, end' ‘ ’)</
{{out}}
Line 50:
The only added optimization is the loop up to n/2 instead of n-1.
With 31 bit integers the limit is 2,147,483,647.
<
PERFECTN CSECT
USING PERFECTN,R13 prolog
Line 96:
PG DC CL12' ' buffer
YREGS
END PERFECTN</
{{out}}
<pre>
Line 108:
Use of optimizations found in Rexx algorithms and use of packed decimal to have bigger numbers.
With 15 digit decimal integers the limit is 999,999,999,999,999.
<
PERFECPO CSECT
USING PERFECPO,R13 prolog
Line 183:
PW2 DS PL16
YREGS
END PERFECPO</
{{out}}
<pre>
Line 197:
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program perfectNumber64.s */
Line 458:
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
<pre>
Perfect : 6
Line 471:
</pre>
=={{header|Action!}}==
<
DEFINE MAXNUM="10000"
CARD ARRAY pds(MAXNUM+1)
Line 494:
FI
OD
RETURN</
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Perfect_numbers.png Screenshot from Atari 8-bit computer]
Line 505:
=={{header|Ada}}==
<
Sum : Natural := 0;
begin
Line 514:
end loop;
return Sum = N;
end Is_Perfect;</
=={{header|ALGOL 60}}==
{{works with|A60}}
<
begin
Line 562:
end
</syntaxhighlight>
{{out}}
<pre>
Line 574:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}}
<
INT sum :=1;
FOR f1 FROM 2 TO ENTIER ( sqrt(candidate)*(1+2*small real) ) WHILE
Line 594:
IF is perfect(i) THEN print((i, new line)) FI
OD
)</
{{Out}}
<pre>
Line 606:
=={{header|ALGOL W}}==
Based on the Algol 68 version.
<
% returns true if n is perfect, false otherwise %
% n must be > 0 %
Line 627:
% test isPerfect %
for n := 2 until 10000 do if isPerfect( n ) then write( n );
end.</
{{out}}
<pre>
Line 639:
===Functional===
{{Trans|JavaScript}}
<
-- perfect :: integer -> bool
Line 746:
end script
end if
end mReturn</
{{Out}}
<
----
===Idiomatic===
====Sum of proper divisors====
<
if (n < 2) then return 0
set sum to 1
Line 783:
if (isPerfect(n)) then set end of output to n
end repeat
return output</
{{output}}
<
====Euclid====
<
-- All the known perfect numbers listed in Wikipedia end with either 6 or 28.
-- These endings are either preceded by odd digits or are the numbers themselves.
Line 813:
if (isPerfect(n)) then set end of output to n
end repeat
return output</
{{output}}
<
====Practical====
But since AppleScript can only physically manage seven of the known perfect numbers, they may as well be in a look-up list for maximum efficiency:
<
if (n > 1.37438691328E+11) then return missing value -- Too high for perfection to be determinable.
return (n is in {6, 28, 496, 8128, 33550336, 8.589869056E+9, 1.37438691328E+11})
end isPerfect</
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
/* ARM assembly Raspberry PI */
Line 904:
/***************************************************/
.include "../affichage.inc"
</syntaxhighlight>
<pre>
Perfect : 6
Line 913:
</pre>
=={{header|Arturo}}==
<
perfect?: $[n][ n = sum divisors n ]
loop 2..1000 'i [
if perfect? i -> print i
]</
=={{header|AutoHotkey}}==
This will find the first 8 perfect numbers.
<
If isMersennePrime(A_Index + 1)
res .= "Perfect number: " perfectNum(A_Index + 1) "`n"
Line 943:
Return false
Return true
}</
=={{header|AWK}}==
<
BEGIN{for(i=1;i<10000;i++)if(perf(i))print i}'
6
28
496
8128</
=={{header|Axiom}}==
{{trans|Mathematica}}
Using the interpreter, define the function:
<
Alternatively, using the Spad compiler:
<
TestPackage() : withma
perfect?: Integer -> Boolean
Line 964:
add
import IntegerNumberTheoryFunctions
perfect? n == reduce("+",divisors n) = 2*n</
Examples (testing 496, testing 128, finding all perfect numbers in 1...10000):
<
perfect? 128
[i for i in 1..10000 | perfect? i]</
{{Out}}
<
false
[6,28,496,8128]</
=={{header|BASIC}}==
{{works with|QuickBasic|4.5}}
<
sum = 0
for i = 1 to n - 1
Line 989:
perf = 0
END IF
END FUNCTION</
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="basic256">
function isPerfect(n)
if (n < 2) or (n mod 2 = 1) then return False
Line 1,014:
next i
end
</syntaxhighlight>
==={{header|IS-BASIC}}===
<
110 FOR X=1 TO 10000
120 IF PERFECT(X) THEN PRINT X;
Line 1,029:
190 NEXT
200 LET PERFECT=N=S
210 END DEF</
==={{header|Sinclair ZX81 BASIC}}===
Call this subroutine and it will (eventually) return <tt>PERFECT</tt> = 1 if <tt>N</tt> is perfect or <tt>PERFECT</tt> = 0 if it is not.
<
2010 FOR F=1 TO N-1
2020 IF N/F=INT (N/F) THEN LET SUM=SUM+F
2030 NEXT F
2040 LET PERFECT=SUM=N
2050 RETURN</
==={{header|True BASIC}}===
<
FUNCTION perf(n)
IF n < 2 or ramainder(n,2) = 1 then LET perf = 0
Line 1,063:
PRINT "Presione cualquier tecla para salir"
END
</syntaxhighlight>
=={{header|BBC BASIC}}==
===BASIC version===
<
IF FNperfect(n%) PRINT n%
NEXT
Line 1,079:
NEXT
IF I% = SQR(N%) S% += I%
= (N% = S%)</
{{Out}}
<pre>
Line 1,090:
===Assembler version===
{{works with|BBC BASIC for Windows}}
<
[OPT 2 :.S% xor edi,edi
.perloop mov eax,ebx : cdq : div ecx : or edx,edx : loopnz perloop : inc ecx
Line 1,099:
IF B% = USRS% PRINT B%
NEXT
END</
{{Out}}
<pre>
Line 1,111:
=={{header|Bracmat}}==
<
= sum i
. 0:?sum
Line 1,128:
& (perf$!n&out$!n|)
)
);</
{{Out}}
<pre>6
Line 1,136:
=={{header|Burlesque}}==
<
<
{6 28 496 8128}</
=={{header|C}}==
{{trans|D}}
<
#include "math.h"
Line 1,170:
return 0;
}</
Using functions from [[Factors of an integer#Prime factoring]]:
<
{
int j;
Line 1,186:
return 0;
}</
=={{header|C sharp|C#}}==
{{trans|C++}}
<
{
Console.WriteLine("Perfect numbers from 1 to 33550337:");
Line 1,213:
return sum == num ;
}</
===Version using Lambdas, will only work from version 3 of C# on===
<
{
Console.WriteLine("Perfect numbers from 1 to 33550337:");
Line 1,231:
{
return Enumerable.Range(1, num - 1).Sum(n => num % n == 0 ? n : 0 ) == num;
}</
=={{header|C++}}==
{{works with|gcc}}
<
using namespace std ;
Line 1,254:
return 0 ;
}
</syntaxhighlight>
=={{header|Clojure}}==
<
(if (< n 4)
[1]
Line 1,265:
(defn perfect? [n]
(= (reduce + (proper-divisors n)) n))</
{{trans|Haskell}}
<
(->> (for [i (range 1 n)] :when (zero? (rem n i))] i)
(reduce +)
(= n)))</
===Functional version===
<
(= (reduce + (filter #(zero? (rem n %)) (range 1 n))) n))</
=={{header|COBOL}}==
Line 1,281:
{{works with|Visual COBOL}}
main.cbl:
<
IDENTIFICATION DIVISION.
Line 1,304:
GOBACK
.
END PROGRAM perfect-main.</
perfect.cbl:
<
FUNCTION-ID. perfect.
Line 1,343:
GOBACK
.
END FUNCTION perfect.</
=={{header|CoffeeScript}}==
Optimized version, for fun.
<
do_factors_add_up_to n, 2*n
Line 1,395:
for n in known_perfects
throw Error("fail") unless is_perfect_number(n)
throw Error("fail") if is_perfect_number(n+1)</
{{Out}}
<pre>
Line 1,407:
=={{header|Common Lisp}}==
{{trans|Haskell}}
<
(= n (loop for i from 1 below n when (= 0 (mod n i)) sum i)))</
=={{header|D}}==
===Functional Version===
<
bool isPerfectNumber1(in uint n) pure nothrow
Line 1,423:
void main() {
iota(1, 10_000).filter!isPerfectNumber1.writeln;
}</
{{out}}
<pre>[6, 28, 496, 8128]</pre>
Line 1,429:
===Faster Imperative Version===
{{trans|Algol}}
<
bool isPerfectNumber2(in int n) pure nothrow {
Line 1,449:
void main() {
10_000.iota.filter!isPerfectNumber2.writeln;
}</
{{out}}
<pre>[6, 28, 496, 8128]</pre>
Line 1,457:
=={{header|Dart}}==
=== Explicit Iterative Version ===
<
* Function to test if a number is a perfect number
* A number is a perfect number if it is equal to the sum of all its divisors
Line 1,479:
// We return the test if n is equal to sumOfDivisors
return n == sumOfDivisors;
}</
=== Compact Version ===
{{trans|Julia}}
<
n == new List.generate(n-1, (i) => n%(i+1) == 0 ? i+1 : 0).fold(0, (p,n)=>p+n);</
In either case, if we test to find all the perfect numbers up to 1000, we get:
<
new List.generate(1000,(i)=>i+1).where(isPerfect).forEach(print);</
{{out}}
<pre>6
Line 1,497:
=={{header|Dyalect}}==
<
var sum = 0
for i in 1..<num {
Line 1,517:
print("\(x) is perfect")
}
}</
=={{header|E}}==
<
def isPerfectNumber(x :int) {
var sum := 0
Line 1,528:
}
return sum <=> x
}</
=={{header|Eiffel}}==
<syntaxhighlight lang="eiffel">
class
APPLICATION
Line 1,573:
end
</syntaxhighlight>
{{out}}
<pre>
Line 1,584:
=={{header|Elena}}==
ELENA 4.x:
<
import system'math;
import extensions;
Line 1,603:
console.readChar()
}</
{{out}}
<pre>
Line 1,613:
=={{header|Elixir}}==
<
def is_perfect(1), do: false
def is_perfect(n) when n > 1 do
Line 1,625:
end
IO.inspect (for i <- 1..10000, RC.is_perfect(i), do: i)</
{{out}}
Line 1,633:
=={{header|Erlang}}==
<
X == lists:sum([N || N <- lists:seq(1,X-1), X rem N == 0]).</
=={{header|ERRE}}==
<
PROCEDURE PERFECT(N%->OK%)
Line 1,655:
IF OK% THEN PRINT(N%)
END FOR
END PROGRAM</
{{Out}}
<pre>
Line 1,665:
=={{header|F_Sharp|F#}}==
<
for i in 1..10000 do if (perf i) then printfn "%i is perfect" i</
{{Out}}
<pre>6 is perfect
Line 1,675:
=={{header|Factor}}==
<
IN: rosettacode.perfect-numbers
: perfect? ( n -- ? ) [ divisors sum ] [ 2 * ] bi = ;</
=={{header|FALSE}}==
<
45p;!." "28p;!. { 0 -1 }</
=={{header|Forth}}==
<
1
over 2/ 1+ 2 ?do
over i mod 0= if i + then
loop
= ;</
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<
LOGICAL :: isPerfect
INTEGER, INTENT(IN) :: n
Line 1,705:
END DO
IF (factorsum == n) isPerfect = .TRUE.
END FUNCTION isPerfect</
=={{header|FreeBASIC}}==
{{trans|C (with some modifications)}}
<
Function isPerfect(n As Integer) As Boolean
Line 1,732:
Print
Print "Press any key to quit"
Sleep</
{{out}}
Line 1,741:
=={{header|Frink}}==
<
println[select[1 to 1000, isPerfect]]</
{{out}}
Line 1,749:
=={{header|FunL}}==
<
println( (1..500).filter(perfect) )</
{{out}}
Line 1,760:
=={{header|GAP}}==
<
# [ 6, 28, 496, 8128 ]</
=={{header|Go}}==
<
import "fmt"
Line 1,802:
}
</syntaxhighlight>
{{Out}}
<pre>
Line 1,813:
=={{header|Groovy}}==
Solution:
<
n > 4 && (n == (2..Math.sqrt(n)).findAll { n % it == 0 }.inject(1) { factorSum, i -> factorSum += i + n/i })
}</
Test program:
<
{{Out}}
<pre>6
Line 1,825:
=={{header|Haskell}}==
<
n == sum [i | i <- [1..n-1], n `mod` i == 0]</
Create a list of known perfects:
<
(\x -> (2 ^ x - 1) * (2 ^ (x - 1))) <$>
filter (\x -> isPrime x && isPrime (2 ^ x - 1)) maybe_prime
Line 1,847:
main = do
mapM_ print $ take 10 perfect
mapM_ (print . (\x -> (x, isPerfect x))) [6, 27, 28, 29, 496, 8128, 8129]</
or, restricting the search space to improve performance:
<
isPerfect n =
let lows = filter ((0 ==) . rem n) [1 .. floor (sqrt (fromIntegral n))]
Line 1,866:
main :: IO ()
main = print $ filter isPerfect [1 .. 10000]</
{{Out}}
<pre>[6,28,496,8128]</pre>
=={{header|HicEst}}==
<
IF( perfect(i) ) WRITE() i
ENDDO
Line 1,882:
ENDDO
perfect = sum == n
END</
=={{header|Icon}} and {{header|Unicon}}==
<
limit := \arglist[1] | 100000
write("Perfect numbers from 1 to ",limit,":")
Line 1,899:
end
link factors</
{{libheader|Icon Programming Library}} [http://www.cs.arizona.edu/icon/library/src/procs/factors.icn Uses divisors from factors]
Line 1,912:
=={{header|J}}==
<
Examples of use, including extensions beyond those assumptions:
<
1
I. is_perfect i. 100000
Line 1,929:
0 0 0 0 0 0 0 0 1 0
is_perfect 191561942608236107294793378084303638130997321548169216x
1</
More efficient version based on [http://jsoftware.com/pipermail/programming/2014-June/037695.html comments] by Henry Rich and Roger Hui (comment train seeded by Jon Hough).
=={{header|Java}}==
<
int sum= 0;
for(int i= 1;i < n;i++){
Line 1,942:
}
return sum == n;
}</
Or for arbitrary precision:[[Category:Arbitrary precision]]
<
public static boolean perf(BigInteger n){
Line 1,955:
}
return sum.equals(n);
}</
=={{header|JavaScript}}==
Line 1,962:
{{trans|Java}}
<
{
var sum = 1, i, sqrt=Math.floor(Math.sqrt(n));
Line 1,982:
if (is_perfect(i))
print(i);
}</
{{Out}}
Line 1,996:
Naive version (brute force)
<
function perfect(n) {
Line 2,014:
return range(nFrom, nTo).filter(perfect);
})(1, 10000);</
Output:
<
Much faster (more efficient factorisation)
<
function perfect(n) {
Line 2,044:
return range(nFrom, nTo).filter(perfect)
})(1, 10000);</
Output:
<
Note that the filter function, though convenient and well optimised, is not strictly necessary.
Line 2,054:
(Monadic return/inject for lists is simply lambda x --> [x], inlined here, and fail is [].)
<
// MONADIC CHAIN (bind) IN LIEU OF FILTER
Line 2,088:
}
})(1, 10000);</
Output:
<
====ES6====
<
const main = () =>
enumFromTo(1, 10000).filter(perfect);
Line 2,120:
// MAIN ---
return main();
})();</
{{Out}}
<
=={{header|jq}}==
<syntaxhighlight lang="jq">
def is_perfect:
. as $in
Line 2,133:
# Example:
range(1;10001) | select( is_perfect )</
{{Out}}
$ jq -n -f is_perfect.jq
Line 2,144:
{{works with|Julia|0.6}}
<
perfects(n::Integer) = filter(isperfect, 1:n)
@show perfects(10000)</
{{out}}
Line 2,154:
=={{header|K}}==
{{trans|J}}
<
perfect 33550336
1
Line 2,169:
(0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0)</
=={{header|Kotlin}}==
{{trans|C}}
<
fun isPerfect(n: Int): Boolean = when {
Line 2,196:
println("The first five perfect numbers are:")
for (i in 2 .. 33550336) if (isPerfect(i)) print("$i ")
}</
{{out}}
Line 2,208:
=={{header|Lasso}}==
<
define isPerfect(n::integer) => {
Line 2,222:
with x in generateSeries(1, 10000)
where isPerfect(#x)
select #x</
{{Out}}
<syntaxhighlight lang
=={{header|Liberty BASIC}}==
<
if perfect( n) =1 then print n; " is perfect."
next n
Line 2,245:
perfect =0
end if
end function</
=={{header|Lingo}}==
<
sum = 1
cnt = n/2
Line 2,255:
end repeat
return sum=n
end</
=={{header|Logo}}==
<
output equal? :n apply "sum filter [equal? 0 modulo :n ?] iseq 1 :n/2
end</
=={{header|Lua}}==
<
local sum = 0
for i = 1, x-1 do
Line 2,269:
end
return sum == x
end</
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module PerfectNumbers {
Function Is_Perfect(n as decimal) {
Line 2,344:
PerfectNumbers
</syntaxhighlight>
{{out}}
Line 2,363:
=={{header|M4}}==
<
`ifelse($#,0,``$0'',
`ifelse(eval($2<=$3),1,
Line 2,381:
for(`x',`2',`33550336',
`ifelse(isperfect(x),1,`x
')')</
=={{header|MAD}}==
<
R FUNCTION THAT CHECKS IF NUMBER IS PERFECT
Line 2,403:
PRINT COMMENT $ $
END OF PROGRAM
</syntaxhighlight>
{{out}}
Line 2,414:
=={{header|Maple}}==
<
isperfect(6);
true</
=={{header|Mathematica}} / {{header|Wolfram Language}}==
Custom function:
<
Examples (testing 496, testing 128, finding all perfect numbers in 1...10000):
<
PerfectQ[128]
Flatten[PerfectQ/@Range[10000]//Position[#,True]&]</
gives back:
<syntaxhighlight lang="mathematica">True
False
{6,28,496,8128}</
=={{header|MATLAB}}==
Standard algorithm:
<
total = 0;
for k = 1:n-1
Line 2,440:
end
perf = total == n;
end</
Faster algorithm:
<
if n < 2
perf = false;
Line 2,461:
perf = total == n;
end
end</
=={{header|Maxima}}==
<
infix("..")$
Line 2,470:
sublist(1 .. 10000, perfectp);
/* [6, 28, 496, 8128] */</
=={{header|MAXScript}}==
<
(
local sum = 0
Line 2,484:
)
sum == n
)</
=={{header|Microsoft Small Basic}}==
{{trans|BBC BASIC}}
<
For n = 2 To 10000 Step 2
VerifyIfPerfect()
Line 2,518:
EndIf
EndSub
</syntaxhighlight>
=={{header|Modula-2}}==
{{trans|BBC BASIC}}
{{works with|ADW Modula-2|any (Compile with the linker option ''Console Application'').}}
<
MODULE PerfectNumbers;
Line 2,567:
END;
END PerfectNumbers.
</syntaxhighlight>
=={{header|Nanoquery}}==
{{trans|Python}}
<
sum = 0
for i in range(1, n - 1)
Line 2,579:
end
return sum = n
end</
=={{header|Nim}}==
<
proc isPerfect(n: int): bool =
Line 2,595:
for n in 2..10_000:
if n.isPerfect:
echo n</
{{out}}
Line 2,604:
=={{header|Objeck}}==
<
class Test {
function : Main(args : String[]) ~ Nil {
Line 2,626:
}
}
}</
=={{header|OCaml}}==
<
let sum = ref 0 in
for i = 1 to n-1 do
Line 2,635:
sum := !sum + i
done;
!sum = n</
Functional style:
<
let rec (--) a b =
if a > b then
Line 2,644:
a :: (a+1) -- b
let perf n = n = List.fold_left (+) 0 (List.filter (fun i -> n mod i = 0) (1 -- (n-1)))</
=={{header|Oforth}}==
<
{{out}}
Line 2,657:
=={{header|ooRexx}}==
<
loop i = 1 to 10000
if perfectNumber(i) then say i "is a perfect number"
Line 2,673:
end
return sum = n</
{{out}}
<pre>6 is a perfect number
Line 2,681:
=={{header|Oz}}==
<
fun {IsPerfect N}
fun {IsNFactor I} N mod I == 0 end
Line 2,692:
in
{Show {Filter {List.number 1 10000 1} IsPerfect}}
{Show {IsPerfect 33550336}}</
=={{header|PARI/GP}}==
Uses built-in method. Faster tests would use the LL test for evens and myriad results on OPNs otherwise.
<
Show perfect numbers
<
if(isprime(2^p-1),
print(p"\t",(2^p-1)*2^(p-1))))</
Faster with Lucas-Lehmer test
<
while(p<2281,
if(isprime(p),
Line 2,710:
if(s==0 || p==2,
print("(2^"p"-1)2^("p"-1)=\t"n1*n"\n")));
p++; n1=n+1; n=2*n+1)</
{{Out}}
<pre>(2^2-1)2^(2-1)= 6
Line 2,724:
=={{header|Pascal}}==
<
function isPerfect(number: longint): boolean;
Line 2,746:
if isPerfect(candidate) then
writeln (candidate, ' is a perfect number.');
end.</
{{Out}}
<pre>
Line 2,759:
=={{header|Perl}}==
=== Functions ===
<
my $n = shift;
my $sum = 0;
Line 2,768:
}
return $sum == $n;
}</
Functional style:
<
sub perf {
my $n = shift;
$n == sum(0, grep {$n % $_ == 0} 1..$n-1);
}</
=== Modules ===
The functions above are terribly slow. As usual, this is easier and faster with modules. Both ntheory and Math::Pari have useful functions for this.
{{libheader|ntheory}}
A simple predicate:
<
sub is_perfect { my $n = shift; divisor_sum($n) == 2*$n; }</
Use this naive method to show the first 5. Takes about 15 seconds:
<
for (1..33550336) {
print "$_\n" if divisor_sum($_) == 2*$_;
}</
Or we can be clever and look for 2^(p-1) * (2^p-1) where 2^p -1 is prime. The first 20 takes about a second.
<
use bigint;
forprimes {
my $n = 2**$_ - 1;
print "$_\t", $n * 2**($_-1),"\n" if is_prime($n);
} 2, 4500;</
{{out}}
<pre>
Line 2,810:
We can speed this up even more using a faster program for printing the large results, as well as a faster primality solution. The first 38 in about 1 second with most of the time printing the large results. Caveat: this goes well past the current bound for odd perfect numbers and does not check for them.
<
use Math::GMP qw/:constant/;
forprimes {
print "$_\t", (2**$_-1)*2**($_-1),"\n" if is_mersenne_prime($_);
} 7_000_000;</
In addition to generating even perfect numbers, we can also have a fast function which returns true when a given even number is perfect:
<
sub is_even_perfect {
Line 2,826:
($m >> $v) == 1 || return;
is_mersenne_prime($v + 1);
}</
=={{header|Phix}}==
<!--<
<span style="color: #008080;">function</span> <span style="color: #000000;">is_perfect</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">factors</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">))=</span><span style="color: #000000;">n</span>
Line 2,837:
<span style="color: #008080;">if</span> <span style="color: #000000;">is_perfect</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">i</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</
{{out}}
<pre>
Line 2,847:
=== gmp version ===
{{libheader|Phix/mpfr}}
<!--<
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Perfect_numbers.exw (includes native version above)</span>
Line 2,862:
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_free</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<!--</
{{out}}
<pre>
Line 2,881:
=={{header|PHP}}==
{{trans|C++}}
<
{
$sum = 0;
Line 2,897:
if(is_perfect($num))
echo $num . PHP_EOL;
}</
=={{header|Picat}}==
===Simple divisors/1 function===
First is the slow <code>perfect1/1</code> that use the simple divisors/1 function:
<
println(perfect1=[I : I in 1..10_000, perfect1(I)]),
nl.
perfect1(N) => sum(divisors(N)) == N.
divisors(N) = [J: J in 1..1+N div 2, N mod J == 0].</
{{out}}
Line 2,914:
===Using formula for perfect number candidates===
The formula for perfect number candidates is: 2^(p-1)*(2^p-1) for prime p. This is used to find some more perfect numbers in reasonable time. <code>perfect2/1</code> is a faster version of checking if a number is perfect.
<
println("Using the formula: 2^(p-1)*(2^p-1) for prime p"),
foreach(P in primes(32))
Line 2,953:
% I is not a divisor of N.
sum_divisors(I,N,Sum0,Sum) =>
sum_divisors(I+1,N,Sum0,Sum).</
{{out}}
Line 2,971:
The perfect numbers are printed only if they has < 80 digits, otherwise the number of digits are shown. The program stops when reaching a number with more than 100 000 digits. (Note: The major time running this program is getting the number of digits.)
<
ValidP = [2, 3, 5, 7, 13, 17, 19, 31, 61, 89, 107, 127, 521, 607,
1279, 2203, 2281, 3217, 4253, 4423, 9689, 9941, 11213,
Line 2,992:
end
end,
nl.</
{{out}}
Line 3,028:
=={{header|PicoLisp}}==
<
(let C 0
(for I (/ N 2)
(and (=0 (% N I)) (inc 'C I)) )
(= C N) ) )</
<
(let (C 1 Stop (sqrt N))
(for (I 2 (<= I Stop) (inc I))
Line 3,040:
(=0 (% N I))
(inc 'C (+ (/ N I) I)) ) )
(= C N) ) )</
=={{header|PL/I}}==
<
declare n fixed;
declare sum fixed;
Line 3,053:
end;
return (sum=n);
end perfect;</
==={{header|PL/I-80}}===
<
%replace
Line 3,097:
end isperfect;
end perfect_search;</
{{out}}
Line 3,111:
=={{header|PL/M}}==
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)
<
/* DIVISORS */
/* CP/M SYSTEM CALL AND I/O ROUTINES */
Line 3,161:
END;
END;
EOF</
{{out}}
<pre>
Line 3,170:
{{Trans|Action!}}
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)
<
/* DIVISORS */
/* CP/M SYSTEM CALL AND I/O ROUTINES */
Line 3,213:
END;
END;
EOF</
{{out}}
<pre>
Line 3,223:
=={{header|PowerShell}}==
<
{
$sum=0
Line 3,236:
}
Returns "True" if the given number is perfect and "False" if it's not.</
=={{header|Prolog}}==
===Classic approach===
Works with SWI-Prolog
<
Q is X / N,
( 0 is X mod N -> (Q = N -> TT1 is N + TT;
Line 3,254:
perfect_numbers(N, L) :-
numlist(2, N, LN),
include(perfect, LN, L).</
===Faster method===
Since a perfect number is of the form 2^(n-1) * (2^n - 1), we can eliminate a lot of candidates by merely factoring out the 2s and seeing if the odd portion is (2^(n+1)) - 1.
<syntaxhighlight lang="prolog">
perfect(N) :-
factor_2s(N, Chk, Exp),
Line 3,285:
N mod D =\= 0,
D2 is D + A, prime(N, D2, As).
</syntaxhighlight>
{{out}}
<pre>
Line 3,298:
===Functional approach===
Works with SWI-Prolog and module lambda, written by <b>Ulrich Neumerkel</b> found there http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl
<
is_divisor(V, N) :-
Line 3,334:
%% f_compose_1(Pred1, Pred2, Pred1(Pred2)).
%
f_compose_1(F,G, \X^Z^(call(G,X,Y), call(F,Y,Z))).</
=={{header|PureBasic}}==
<
Protected summa, i=1, result=#False
Repeat
Line 3,349:
EndIf
ProcedureReturn result
EndProcedure</
=={{header|Python}}==
Line 3,378:
===Python: Procedural===
<
sum = 0
for i in range(1, n):
if n % i == 0:
sum += i
return sum == n</
===Python: Optimised Procedural===
<
def factor2(n):
Line 3,407:
def perf4(n):
"Using most efficient prime factoring routine from: http://rosettacode.org/wiki/Factors_of_an_integer#Python"
return 2 * n == sum(factor2(n))</
===Python: Functional===
<
return n == sum(i for i in range(1, n) if n % i == 0)
print (
list(filter(perf2, range(1, 10001)))
)</
<
from math import sqrt
Line 3,453:
if __name__ == '__main__':
main()</
{{Out}}
<pre>[6, 28, 496, 8128]</pre>
Line 3,461:
<code>factors</code> is defined at [http://rosettacode.org/wiki/Factors_of_an_integer#Quackery Factors of an integer].
<
[ factors -1 pluck dip sum = ] is perfect ( n --> n )
Line 3,468:
10000 times
[ i^ 1+ perfect if [ i^ 1+ echo cr ] ]
</syntaxhighlight>
{{out}}
Line 3,480:
=={{header|R}}==
<
if (n==0|n==1) return(FALSE)
s <- seq (1,n-1)
Line 3,490:
# Usage - Warning High Memory Usage
is.perf(28)
sapply(c(6,28,496,8128,33550336),is.perf)</
=={{header|Racket}}==
<
(require math)
Line 3,503:
; filtering to only even numbers for better performance
(filter perfect? (filter even? (range 1e5)))
;-> '(0 6 28 496 8128)</
=={{header|Raku}}==
(formerly Perl 6)
Naive (very slow) version
<syntaxhighlight lang="raku"
# used as
put ((1..Inf).hyper.grep: {.&is-perf})[^4];</
{{out}}
<pre>6 28 496 8128</pre>
Much, much faster version:
<syntaxhighlight lang="raku"
my @perfects = lazy gather for @primes {
my $n = 2**$_ - 1;
Line 3,521:
}
.put for @perfects[^12];</
{{out}}
Line 3,538:
=={{header|REBOL}}==
<
sum: 0
repeat i (n - 1) [
Line 3,546:
]
sum = n
]</
=={{header|REXX}}==
===Classic REXX version of ooRexx===
This version is a '''Classic Rexx''' version of the '''ooRexx''' program as of 14-Sep-2013.
<
do i=1 to 10000 /*statement changed: LOOP ──► DO*/
if perfectNumber(i) then say i "is a perfect number"
Line 3,562:
if n//i==0 then sum=sum+i /*statement changed: sum += i */
end
return sum=n</
'''output''' when using the default of 10000:
<pre>
Line 3,574:
This version is a '''Classic REXX''' version of the '''PL/I''' program as of 14-Sep-2013, a REXX '''say''' statement
<br>was added to display the perfect numbers. Also, an epilog was written for the re-worked function.
<
parse arg low high . /*obtain the specified number(s).*/
if high=='' & low=='' then high=34000000 /*if no arguments, use a range. */
Line 3,590:
if n//i==0 then sum=sum+i /*I is a factor of N, so add it.*/
end /*i*/
return sum=n /*if the sum matches N, perfect! */</
'''output''' when using the input defaults of: <tt> 1 10000 </tt>
Line 3,600:
:::* testing bypasses the test of the first and last factors
:::* the ''corresponding factor'' is also used when a factor is found
<
parse arg low high . /*obtain optional arguments from the CL*/
if high=='' & low=="" then high=34000000 /*if no arguments, then use a range. */
Line 3,620:
s = s + j + x%j /* ··· add it and the other factor. */
end /*j*/ /*(above) is marginally faster. */
return s==x /*if the sum matches X, it's perfect! */</
'''output''' when using the default inputs:
<pre>
Line 3,635:
===optimized using digital root===
This REXX version makes use of the fact that all ''known'' perfect numbers > 6 have a ''digital root'' of '''1'''.
<
parse arg low high . /*obtain the specified number(s). */
if high=='' & low=="" then high=34000000 /*if no arguments, then use a range. */
Line 3,662:
s = s + j + x%j /*··· add it and the other factor. */
end /*j*/ /*(above) is marginally faster. */
return s==x /*if the sum matches X, it's perfect! */</
'''output''' is the same as the traditional version and is about '''5.3''' times faster (testing '''34,000,000''' numbers).
===optimized using only even numbers===
This REXX version uses the fact that all ''known'' perfect numbers are ''even''.
<
parse arg low high . /*obtain optional arguments from the CL*/
if high=='' & low=="" then high=34000000 /*if no arguments, then use a range. */
Line 3,695:
s = s + j + x%j /* ··· add it and the other factor. */
end /*j*/ /*(above) is marginally faster. */
return s==x /*if sum matches X, then it's perfect!*/</
'''output''' is the same as the traditional version and is about '''11.5''' times faster (testing '''34,000,000''' numbers).
===Lucas-Lehmer method===
This version uses memoization to implement a fast version of the Lucas-Lehmer test.
<
parse arg low high . /*obtain the optional arguments from CL*/
if high=='' & low=="" then high=34000000 /*if no arguments, then use a range. */
Line 3,732:
s=s + j + x%j /*··· add it and the other factor. */
end /*j*/ /*(above) is marginally faster. */
return s==x /*if the sum matches X, it's perfect!*/</
'''output''' is the same as the traditional version and is about '''75''' times faster (testing '''34,000,000''' numbers).
Line 3,742:
An integer square root function was added to limit the factorization of a number.
<
parse arg low high . /*obtain optional arguments from the CL*/
if high=='' & low=="" then high=34000000 /*No arguments? Then use a range. */
Line 3,788:
if x//j==0 then s=s+j+x%j /*J divisible by X? Then add J and X÷J*/
end /*j*/
return s==x /*if the sum matches X, then perfect! */</
'''output''' is the same as the traditional version and is about '''500''' times faster (testing '''34,000,000''' numbers). <br><br>
=={{header|Ring}}==
<
for i = 1 to 10000
if perfect(i) see i + nl ok
Line 3,804:
if sum = n return 1 else return 0 ok
return sum
</syntaxhighlight>
=={{header|Ruby}}==
<
sum = 0
for i in 1...n
Line 3,813:
end
sum == n
end</
Functional style:
<
n == (1...n).select {|i| n % i == 0}.inject(:+)
end</
Faster version:
<
divisors = []
for i in 1..Integer.sqrt(n)
Line 3,825:
end
divisors.uniq.inject(:+) == 2*n
end</
Test:
<
puts n if perf(n)
end</
{{out}}
<pre>
Line 3,839:
===Fast (Lucas-Lehmer)===
Generate and memoize perfect numbers as needed.
<
def mersenne_prime_pow?(p)
Line 3,863:
p perfect?(13164036458569648337239753460458722910223472318386943117783728128)
p Time.now - t1
</syntaxhighlight>
{{out}}
<pre>
Line 3,873:
=={{header|Run BASIC}}==
<
if perf(i) then print i;" ";
next i
Line 3,882:
next i
IF sum = n THEN perf = 1
END FUNCTION</
{{Out}}
<pre>6 28 496 8128</pre>
=={{header|Rust}}==
<
fn main ( ) {
fn factor_sum(n: i32) -> i32 {
Line 3,909:
perfect_nums(10000);
}
</syntaxhighlight>
=={{header|SASL}}==
Copied from the SASL manual, page 22:
<syntaxhighlight lang="sasl">
|| The function which takes a number and returns a list of its factors (including one but excluding itself)
|| can be written
Line 3,920:
|| we can write the list of all perfect numbers as
perfects = { n <- 1... ; n = sum(factors n) }
</syntaxhighlight>
=={{header|S-BASIC}}==
<
$lines
Line 3,963:
end
</syntaxhighlight>
{{out}}
<pre>
Line 3,975:
=={{header|Scala}}==
<
'''or'''
<
(for (x <- 2 to n/2 if n % x == 0) yield x).sum + 1 == n
</syntaxhighlight>
=={{header|Scheme}}==
<
(let loop ((i 1)
(sum 0))
Line 3,992:
(loop (+ i 1) (+ sum i)))
(else
(loop (+ i 1) sum)))))</
=={{header|Seed7}}==
<
const func boolean: isPerfect (in integer: n) is func
Line 4,026:
end if;
end for;
end func;</
{{Out}}
<pre>
Line 4,037:
=={{header|Sidef}}==
<
n.sigma == 2*n
}
Line 4,043:
for n in (1..10000) {
say n if is_perfect(n)
}</
Alternatively, a more efficient check for even perfect numbers:
<
var square = (8*n + 1)
Line 4,059:
for n in (1..10000) {
say n if is_even_perfect(n)
}</
{{out}}
Line 4,070:
=={{header|Simula}}==
<
BEGIN
INTEGER SUM;
Line 4,077:
SUM := SUM + I;
PERF := SUM = N;
END PERF;</
=={{header|Slate}}==
<
[
(((2 to: n // 2 + 1) select: [| :m | (n rem: m) isZero])
inject: 1 into: #+ `er) = n
].</
=={{header|Smalltalk}}==
<
"Translation of the C version; this is faster..."
Line 4,107:
inject: 1 into: [ :a :b | a + b ] ) = self
]
].</
<
=={{header|Swift}}==
{{trans|Java}}
<
var sum = 0
for i in 1..<n {
Line 4,127:
println(i)
}
}</
{{out}}
<pre>
Line 4,137:
=={{header|Tcl}}==
<
set sum 0
for {set i 1} {$i <= $n} {incr i} {
Line 4,143:
}
expr {$sum == 2*$n}
}</
=={{header|Ursala}}==
<
#import nat
is_perfect = ~&itB&& ^(~&,~&t+ iota); ^E/~&l sum:-0+ ~| not remainder</
This test program applies the function to a list of the first five hundred natural
numbers and deletes the imperfect ones.
<
examples = is_perfect*~ iota 500</
{{Out}}
<pre><6,28,496></pre>
Line 4,161:
{{trans|Phix}}
Using [[Factors_of_an_integer#VBA]], slightly adapted.
<
Application.Volatile
Dim i As Long
Line 4,189:
If is_perfect(i) Then Debug.Print i
Next i
End Sub</
<pre> 6
28
Line 4,196:
=={{header|VBScript}}==
<
IsPerfect = False
i = n - 1
Line 4,212:
WScript.StdOut.Write IsPerfect(CInt(WScript.Arguments(0)))
WScript.StdOut.WriteLine</
{{out}}
Line 4,228:
=={{header|Vlang}}==
{{trans|go}}
<
mut sum := i64(0)
for i := i64(1); i < n; i++ {
Line 4,255:
}
}
}</
{{Out}}
<pre>
Line 4,268:
{{trans|D}}
Restricted to the first four perfect numbers as the fifth one is very slow to emerge.
<
if (n <= 2) return false
var tot = 1
Line 4,291:
i = i + 2 // there are no known odd perfect numbers
}
System.print()</
{{out}}
Line 4,301:
{{libheader|Wren-math}}
This makes use of the fact that all known perfect numbers are of the form <big> (2<sup>''n''</sup> - 1) × 2<sup>''n'' - 1</sup></big> where <big> (2<sup>''n''</sup> - 1)</big> is prime and finds the first seven perfect numbers instantly. The numbers are too big after that to be represented accurately by Wren.
<
var isPerfect = Fn.new { |n|
Line 4,330:
p = p + 1
}
System.print()</
{{out}}
Line 4,338:
=={{header|XPL0}}==
<
func Perfect(N); \Return 'true' if N is a perfect number
Line 4,355:
if Perfect(N) then [IntOut(0, N); CrLf(0)];
];
]</
{{out}}
Line 4,369:
=={{header|Yabasic}}==
{{trans|True BASIC}}
<
sub isPerfect(n)
if (n < 2) or mod(n, 2) = 1 then return false : endif
Line 4,386:
print
end
</syntaxhighlight>
=={{header|Zig}}==
<syntaxhighlight lang="zig">
const std = @import("std");
const expect = std.testing.expect;
Line 4,420:
expect(propersum(30) == 42);
}
</syntaxhighlight>
{{Out}}
<pre>
Line 4,427:
=={{header|zkl}}==
{{trans|D}}
<
{ n == [1..n-1].filter('wrap(i){ n % i == 0 }).sum(); }</
{{out}}
<pre>
|