Perfect numbers: Difference between revisions
m
→{{header|EasyLang}}
({{header|Burlesque}}) |
|||
(32 intermediate revisions by 17 users not shown) | |||
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 534:
integer sum, f1, f2;
sum := 1;
f1 :=
for f1 := f1 + 1 while (f1 * f1) <= n do
begin
if mod(n, f1) = 0 then
Line 543:
if f2 > f1 then sum := sum + f2;
end;
isperfect := (sum = n);
end;
Line 563 ⟶ 562:
end
</syntaxhighlight>
{{out}}
<pre>
Line 575 ⟶ 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 595 ⟶ 594:
IF is perfect(i) THEN print((i, new line)) FI
OD
)</
{{Out}}
<pre>
Line 607 ⟶ 606:
=={{header|ALGOL W}}==
Based on the Algol 68 version.
<
% returns true if n is perfect, false otherwise %
% n must be > 0 %
Line 628 ⟶ 627:
% test isPerfect %
for n := 2 until 10000 do if isPerfect( n ) then write( n );
end.</
{{out}}
<pre>
Line 640 ⟶ 639:
===Functional===
{{Trans|JavaScript}}
<
-- perfect :: integer -> bool
Line 747 ⟶ 746:
end script
end if
end mReturn</
{{Out}}
<
----
===Idiomatic===
====Sum of proper divisors====
<
if (n < 2) then return 0
set sum to 1
Line 784 ⟶ 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 814 ⟶ 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 905 ⟶ 904:
/***************************************************/
.include "../affichage.inc"
</syntaxhighlight>
<pre>
Perfect : 6
Line 914 ⟶ 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 944 ⟶ 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 965 ⟶ 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 990 ⟶ 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,015 ⟶ 1,014:
next i
end
</syntaxhighlight>
==={{header|Craft Basic}}===
<syntaxhighlight lang="basic">for n = 1 to 10000
let s = 0
for i = 1 to n / 2
if n % i = 0 then
let s = s + i
endif
next i
if s = n then
print n, " ",
endif
wait
next n</syntaxhighlight>
{{out| Output}}<pre>6 28 496 8128 </pre>
==={{header|IS-BASIC}}===
<
110 FOR X=1 TO 10000
120 IF PERFECT(X) THEN PRINT X;
Line 1,030 ⟶ 1,054:
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,064 ⟶ 1,088:
PRINT "Presione cualquier tecla para salir"
END
</syntaxhighlight>
=={{header|BBC BASIC}}==
===BASIC version===
<
IF FNperfect(n%) PRINT n%
NEXT
Line 1,080 ⟶ 1,104:
NEXT
IF I% = SQR(N%) S% += I%
= (N% = S%)</
{{Out}}
<pre>
Line 1,091 ⟶ 1,115:
===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,100 ⟶ 1,124:
IF B% = USRS% PRINT B%
NEXT
END</
{{Out}}
<pre>
Line 1,112 ⟶ 1,136:
=={{header|Bracmat}}==
<
= sum i
. 0:?sum
Line 1,129 ⟶ 1,153:
& (perf$!n&out$!n|)
)
);</
{{Out}}
<pre>6
Line 1,137 ⟶ 1,161:
=={{header|Burlesque}}==
<
<
{6 28 496 8128}</
=={{header|C}}==
{{trans|D}}
<
#include "math.h"
Line 1,171 ⟶ 1,195:
return 0;
}</
Using functions from [[Factors of an integer#Prime factoring]]:
<
{
int j;
Line 1,187 ⟶ 1,211:
return 0;
}</
=={{header|C sharp|C#}}==
{{trans|C++}}
<
{
Console.WriteLine("Perfect numbers from 1 to 33550337:");
Line 1,214 ⟶ 1,238:
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,232 ⟶ 1,256:
{
return Enumerable.Range(1, num - 1).Sum(n => num % n == 0 ? n : 0 ) == num;
}</
=={{header|C++}}==
{{works with|gcc}}
<
using namespace std ;
Line 1,255 ⟶ 1,279:
return 0 ;
}
</syntaxhighlight>
=={{header|Clojure}}==
<
(if (< n 4)
[1]
Line 1,266 ⟶ 1,290:
(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,282 ⟶ 1,306:
{{works with|Visual COBOL}}
main.cbl:
<
IDENTIFICATION DIVISION.
Line 1,305 ⟶ 1,329:
GOBACK
.
END PROGRAM perfect-main.</
perfect.cbl:
<
FUNCTION-ID. perfect.
Line 1,344 ⟶ 1,368:
GOBACK
.
END FUNCTION perfect.</
=={{header|CoffeeScript}}==
Optimized version, for fun.
<
do_factors_add_up_to n, 2*n
Line 1,396 ⟶ 1,420:
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,408 ⟶ 1,432:
=={{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,424 ⟶ 1,448:
void main() {
iota(1, 10_000).filter!isPerfectNumber1.writeln;
}</
{{out}}
<pre>[6, 28, 496, 8128]</pre>
Line 1,430 ⟶ 1,454:
===Faster Imperative Version===
{{trans|Algol}}
<
bool isPerfectNumber2(in int n) pure nothrow {
Line 1,450 ⟶ 1,474:
void main() {
10_000.iota.filter!isPerfectNumber2.writeln;
}</
{{out}}
<pre>[6, 28, 496, 8128]</pre>
Line 1,458 ⟶ 1,482:
=={{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,480 ⟶ 1,504:
// 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,498 ⟶ 1,522:
=={{header|Dyalect}}==
<
var sum = 0
for i in 1..<num {
Line 1,518 ⟶ 1,542:
print("\(x) is perfect")
}
}</
=={{header|E}}==
<
def isPerfectNumber(x :int) {
var sum := 0
Line 1,529 ⟶ 1,553:
}
return sum <=> x
}</
=={{header|EasyLang}}==
<syntaxhighlight>
fastfunc perf n .
i = 1
while i < n
if n mod i = 0
sum += i
.
i += 1
.
if sum = n
return 1
.
return 0
.
for i = 2 to 10000
if perf i = 1
write i & " "
.
.
</syntaxhighlight>
{{out}}
<pre>
6 28 496 8128
</pre>
=={{header|Eiffel}}==
<syntaxhighlight lang="eiffel">
class
APPLICATION
Line 1,574 ⟶ 1,624:
end
</syntaxhighlight>
{{out}}
<pre>
Line 1,584 ⟶ 1,634:
=={{header|Elena}}==
ELENA
<
import system'math;
import extensions;
Line 1,592 ⟶ 1,642:
{
isPerfect()
= new Range(1, self - 1).selectBy::(n => (self.mod
}
public program()
{
for(int n := 1
{
if(n.isPerfect())
Line 1,604 ⟶ 1,654:
console.readChar()
}</
{{out}}
<pre>
Line 1,614 ⟶ 1,664:
=={{header|Elixir}}==
<
def is_perfect(1), do: false
def is_perfect(n) when n > 1 do
Line 1,626 ⟶ 1,676:
end
IO.inspect (for i <- 1..10000, RC.is_perfect(i), do: i)</
{{out}}
Line 1,634 ⟶ 1,684:
=={{header|Erlang}}==
<
X == lists:sum([N || N <- lists:seq(1,X-1), X rem N == 0]).</
=={{header|ERRE}}==
<
PROCEDURE PERFECT(N%->OK%)
Line 1,656 ⟶ 1,706:
IF OK% THEN PRINT(N%)
END FOR
END PROGRAM</
{{Out}}
<pre>
Line 1,666 ⟶ 1,716:
=={{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,676 ⟶ 1,726:
=={{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,706 ⟶ 1,756:
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,733 ⟶ 1,783:
Print
Print "Press any key to quit"
Sleep</
{{out}}
Line 1,742 ⟶ 1,792:
=={{header|Frink}}==
<
println[select[1 to 1000, isPerfect]]</
{{out}}
Line 1,750 ⟶ 1,800:
=={{header|FunL}}==
<
println( (1..500).filter(perfect) )</
{{out}}
Line 1,758 ⟶ 1,808:
<pre>
(6, 28, 496)
</pre>
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
_maxNum = 10000
local fn IsPerfectNumber( n as long ) as BOOL
—————————————————————————————————————————————
if ( n < 2 ) then exit fn = NO
if ( n mod 2 == 1 ) then exit fn = NO
long sum = 1, q, i
for i = 2 to sqr(n)
if ( n mod i == 0 )
sum += i
q = n / i
if ( q > i ) then sum += q
end if
next
end fn = ( n == sum )
printf @"Perfect numbers in range %ld..%ld",2,_maxNum
long i
for i = 2 To _maxNum
if ( fn IsPerfectNumber(i) ) then print i
next
HandleEvents
</syntaxhighlight>
{{out}}
<pre>
Perfect numbers in range 2..10000
6
28
496
8128
</pre>
=={{header|GAP}}==
<
# [ 6, 28, 496, 8128 ]</
=={{header|Go}}==
<
import "fmt"
Line 1,803 ⟶ 1,891:
}
</syntaxhighlight>
{{Out}}
<pre>
Line 1,814 ⟶ 1,902:
=={{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,826 ⟶ 1,914:
=={{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,848 ⟶ 1,936:
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,867 ⟶ 1,955:
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,883 ⟶ 1,971:
ENDDO
perfect = sum == n
END</
=={{header|Icon}} and {{header|Unicon}}==
<
limit := \arglist[1] | 100000
write("Perfect numbers from 1 to ",limit,":")
Line 1,900 ⟶ 1,988:
end
link factors</
{{libheader|Icon Programming Library}} [http://www.cs.arizona.edu/icon/library/src/procs/factors.icn Uses divisors from factors]
Line 1,913 ⟶ 2,001:
=={{header|J}}==
<
Examples of use, including extensions beyond those assumptions:
<
1
I. is_perfect i. 100000
Line 1,930 ⟶ 2,018:
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,943 ⟶ 2,031:
}
return sum == n;
}</
Or for arbitrary precision:[[Category:Arbitrary precision]]
<
public static boolean perf(BigInteger n){
Line 1,956 ⟶ 2,044:
}
return sum.equals(n);
}</
=={{header|JavaScript}}==
Line 1,963 ⟶ 2,051:
{{trans|Java}}
<
{
var sum = 1, i, sqrt=Math.floor(Math.sqrt(n));
Line 1,983 ⟶ 2,071:
if (is_perfect(i))
print(i);
}</
{{Out}}
Line 1,997 ⟶ 2,085:
Naive version (brute force)
<
function perfect(n) {
Line 2,015 ⟶ 2,103:
return range(nFrom, nTo).filter(perfect);
})(1, 10000);</
Output:
<
Much faster (more efficient factorisation)
<
function perfect(n) {
Line 2,045 ⟶ 2,133:
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,055 ⟶ 2,143:
(Monadic return/inject for lists is simply lambda x --> [x], inlined here, and fail is [].)
<
// MONADIC CHAIN (bind) IN LIEU OF FILTER
Line 2,089 ⟶ 2,177:
}
})(1, 10000);</
Output:
<
====ES6====
<
const main = () =>
enumFromTo(1, 10000).filter(perfect);
Line 2,121 ⟶ 2,209:
// MAIN ---
return main();
})();</
{{Out}}
<
=={{header|jq}}==
<syntaxhighlight lang="jq">
def is_perfect:
. as $in
Line 2,134 ⟶ 2,222:
# Example:
range(1;10001) | select( is_perfect )</
{{Out}}
$ jq -n -f is_perfect.jq
Line 2,145 ⟶ 2,233:
{{works with|Julia|0.6}}
<
perfects(n::Integer) = filter(isperfect, 1:n)
@show perfects(10000)</
{{out}}
Line 2,155 ⟶ 2,243:
=={{header|K}}==
{{trans|J}}
<
perfect 33550336
1
Line 2,170 ⟶ 2,258:
(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,197 ⟶ 2,285:
println("The first five perfect numbers are:")
for (i in 2 .. 33550336) if (isPerfect(i)) print("$i ")
}</
{{out}}
Line 2,207 ⟶ 2,295:
=={{header|LabVIEW}}==
{{VI solution|LabVIEW_Perfect_numbers.png}}
=={{header|Lambdatalk}}==
===simple & slow===
<syntaxhighlight lang="scheme">
{def perf
{def perf.sum
{lambda {:n :sum :i}
{if {>= :i :n}
then {= :sum :n}
else {perf.sum :n
{if {= {% :n :i} 0}
then {+ :sum :i}
else :sum}
{+ :i 1}} }}}
{lambda {:n}
{perf.sum :n 0 2} }}
-> perf
{S.replace \s by space in
{S.map {lambda {:i} {if {perf :i} then :i else}}
{S.serie 2 1000 2}}}
-> 6 28 496 // 5200ms
</syntaxhighlight>
Too slow (and stackoverflow) to go further.
===improved===
<syntaxhighlight lang="scheme">
{def lt_perfect
{def lt_perfect.sum
{lambda {:n :sum :i}
{if {> :i 1}
then {lt_perfect.sum :n
{if {= {% :n :i} 0}
then {+ :sum :i {floor {/ :n :i}}}
else :sum}
{- :i 1}}
else :sum }}}
{lambda {:n}
{let { {:n :n}
{:sqrt {floor {sqrt :n}}}
{:sum {lt_perfect.sum :n 1 {- {floor {sqrt :n}} 0} }}
{:foo {if {= {* :sqrt :sqrt} :n}
then 0
else {floor {/ :n :sqrt}}}}
} {= :n {if {= {% :n :sqrt} 0}
then {+ :sum :sqrt :foo}
else :sum}} }}}
-> lt_perfect
-> {S.replace \s by space in
{S.map {lambda {:i} {if {lt_perfect :i} then :i else}}
{S.serie 6 10000 2}}}
-> 28 496 8128 // 7500ms
</syntaxhighlight>
===calling javascript===
Following the javascript entry.
<syntaxhighlight lang="scheme">
{S.replace \s by space in
{S.map {lambda {:i} {if {js_perfect :i} then :i else}}
{S.serie 2 10000}}}
-> 6 28 496 8128 // 80ms
{script
LAMBDATALK.DICT["js_perfect"] = function() {
function js_perfect(n) {
var sum = 1, i, sqrt=Math.floor(Math.sqrt(n));
for (i = sqrt-1; i>1; i--) {
if (n % i == 0)
sum += i + n/i;
}
if(n % sqrt == 0)
sum += sqrt + (sqrt*sqrt == n ? 0 : n/sqrt);
return sum === n;
}
var args = arguments[0].trim();
return (js_perfect( Number(args) )) ? "true" : "false"
};
}
</syntaxhighlight>
=={{header|Lasso}}==
<
define isPerfect(n::integer) => {
Line 2,223 ⟶ 2,397:
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,246 ⟶ 2,420:
perfect =0
end if
end function</
=={{header|Lingo}}==
<
sum = 1
cnt = n/2
Line 2,256 ⟶ 2,430:
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,270 ⟶ 2,444:
end
return sum == x
end</
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module PerfectNumbers {
Function Is_Perfect(n as decimal) {
Line 2,345 ⟶ 2,519:
PerfectNumbers
</syntaxhighlight>
{{out}}
Line 2,364 ⟶ 2,538:
=={{header|M4}}==
<
`ifelse($#,0,``$0'',
`ifelse(eval($2<=$3),1,
Line 2,382 ⟶ 2,556:
for(`x',`2',`33550336',
`ifelse(isperfect(x),1,`x
')')</
=={{header|MAD}}==
<
R FUNCTION THAT CHECKS IF NUMBER IS PERFECT
Line 2,404 ⟶ 2,578:
PRINT COMMENT $ $
END OF PROGRAM
</syntaxhighlight>
{{out}}
Line 2,415 ⟶ 2,589:
=={{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,441 ⟶ 2,615:
end
perf = total == n;
end</
Faster algorithm:
<
if n < 2
perf = false;
Line 2,462 ⟶ 2,636:
perf = total == n;
end
end</
=={{header|Maxima}}==
<
infix("..")$
Line 2,471 ⟶ 2,645:
sublist(1 .. 10000, perfectp);
/* [6, 28, 496, 8128] */</
=={{header|MAXScript}}==
<
(
local sum = 0
Line 2,485 ⟶ 2,659:
)
sum == n
)</
=={{header|Microsoft Small Basic}}==
{{trans|BBC BASIC}}
<
For n = 2 To 10000 Step 2
VerifyIfPerfect()
Line 2,519 ⟶ 2,693:
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,568 ⟶ 2,742:
END;
END PerfectNumbers.
</syntaxhighlight>
=={{header|Nanoquery}}==
{{trans|Python}}
<
sum = 0
for i in range(1, n - 1)
Line 2,580 ⟶ 2,754:
end
return sum = n
end</
=={{header|Nim}}==
<
proc isPerfect(n: int): bool =
Line 2,596 ⟶ 2,770:
for n in 2..10_000:
if n.isPerfect:
echo n</
{{out}}
Line 2,605 ⟶ 2,779:
=={{header|Objeck}}==
<
class Test {
function : Main(args : String[]) ~ Nil {
Line 2,627 ⟶ 2,801:
}
}
}</
=={{header|OCaml}}==
<
let sum = ref 0 in
for i = 1 to n-1 do
Line 2,636 ⟶ 2,810:
sum := !sum + i
done;
!sum = n</
Functional style:
<
let rec (--) a b =
if a > b then
Line 2,645 ⟶ 2,819:
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,655 ⟶ 2,829:
#isPerfect 10000 seq filter .
[6, 28, 496, 8128]
</pre>
=={{header|Odin}}==
<syntaxhighlight lang="Go">
package perfect_numbers
import "core:fmt"
main :: proc() {
fmt.println("\nPerfect numbers from 1 to 100,000:\n")
for num in 1 ..< 100001 {
if divisor_sum(num) == num {
fmt.print("num:", num, "\n")
}
if num % 10000 == 0 {
fmt.print("Count:", num, "\n")
}
}
}
divisor_sum :: proc(number: int) -> int {
sum := 0
for i in 1 ..< number {
if number % i == 0 {
sum += i}
}
return sum
}
</syntaxhighlight>
{{out}}
<pre>
Perfect numbers from 1 to 100,000:
num: 6
num: 28
num: 496
num: 8128
</pre>
=={{header|ooRexx}}==
<
loop i = 1 to 10000
if perfectNumber(i) then say i "is a perfect number"
Line 2,674 ⟶ 2,881:
end
return sum = n</
{{out}}
<pre>6 is a perfect number
Line 2,682 ⟶ 2,889:
=={{header|Oz}}==
<
fun {IsPerfect N}
fun {IsNFactor I} N mod I == 0 end
Line 2,693 ⟶ 2,900:
in
{Show {Filter {List.number 1 10000 1} IsPerfect}}
{Show {IsPerfect 33550336}}</
=={{header|PARI/GP}}==
===Using built-in methods===
<syntaxhighlight lang="parigp">
isPerfect(n)=sigma(n,-1)==2
</syntaxhighlight>
or
<syntaxhighlight lang="parigp">
isPerfect(n)=sigma(n)==2*n
</syntaxhighlight>
Show perfect numbers
<syntaxhighlight lang="parigp">
forprime(p=2, 2281,
if(isprime(2^p-1),
print(p"\t",(2^p-1)*2^(p-1))))
</syntaxhighlight>
faster alternative showing them still using built-in methods
<syntaxhighlight lang="parigp">
[n|n<-[1..10^4],sigma(n,-1)==2]
</syntaxhighlight>
{{Out}}
<pre>
[6, 28, 496, 8128]
</pre>
===Faster with Lucas-Lehmer test===
<syntaxhighlight lang="parigp">p=2;n=3;n1=2;
while(p<2281,
if(isprime(p),
Line 2,711 ⟶ 2,940:
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,725 ⟶ 2,954:
=={{header|Pascal}}==
<
function isPerfect(number: longint): boolean;
Line 2,747 ⟶ 2,976:
if isPerfect(candidate) then
writeln (candidate, ' is a perfect number.');
end.</
{{Out}}
<pre>
Line 2,760 ⟶ 2,989:
=={{header|Perl}}==
=== Functions ===
<
my $n = shift;
my $sum = 0;
Line 2,769 ⟶ 2,998:
}
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,811 ⟶ 3,040:
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,827 ⟶ 3,056:
($m >> $v) == 1 || return;
is_mersenne_prime($v + 1);
}</
=={{header|Phix}}==
<!--
=== naive/native ===
<syntaxhighlight lang="phix">
function is_perfect(integer n)
return sum(factors(n,-1))=n
end function
for i=2 to 100000 do
if is_perfect(i) then ?i end if
end for
</syntaxhighlight>
{{out}}
<pre>
Line 2,848 ⟶ 3,079:
=== gmp version ===
{{libheader|Phix/mpfr}}
<syntaxhighlight lang="phix">
include mpfr.e
atom t0 = time(), t1 = t0+1
integer maxprime = 4423, -- 19937 (rather slow)
lim = length(get_primes_le(maxprime))
mpz n = mpz_init(), m = mpz_init()
for i=1 to lim do
integer p = get_prime(i)
mpz_ui_pow_ui(n, 2, p)
mpz_sub_ui(n, n, 1)
if mpz_prime(n) then
mpz_ui_pow_ui(m, 2, p-1)
mpz_mul(n, n, m)
string ns = mpz_get_short_str(n,comma_fill:=true),
et = elapsed_short(time()-t0,5,"(%s)")
printf(1, "%d %s %s\n",{p,ns,et})
elsif time()>t1 then
progress("%d/%d (%.1f%%)\r",{p,maxprime,i/lim*100})
t1 = time()+1
end if
end for
?elapsed(time()-t0)
</syntaxhighlight>
{{out}}
<pre>
Line 2,875 ⟶ 3,115:
31 2,305,843,008,139,952,128
61 2,658,455,991,569,831,744,654,692,615,953,842,176
89 191,561,942,608,236,
107 13,164,036,458,569,
127 14,474,011,154,664,
521 23,562,723,457,267,3...,492,160,555,646,976 (314 digits)
607 141,053,783,706,712,...,570,759,537,328,128 (366 digits)
1279 54,162,526,284,365,8...,345,764,984,291,328 (770 digits)
2203 1,089,258,355,057,82...,580,834,453,782,528 (1,327 digits)
2281 99,497,054,337,086,4...,375,675,139,915,776 (1,373 digits)
3217 33,570,832,131,986,7...,888,332,628,525,056 (1,937 digits) (9s)
4253 18,201,749,040,140,4...,848,437,133,377,536 (2,561 digits) (24s)
4423 40,767,271,711,094,4...,020,642,912,534,528 (2,663 digits) (28s)
"28.4s"
</pre>
Beyond that it gets rather slow:
<pre>
9689 11,434,731,753,038,6...,982,558,429,577,216 (5,834 digits) (6:28)
9941 598,885,496,387,336,...,478,324,073,496,576 (5,985 digits) (7:31)
11213 3,959,613,212,817,94...,255,702,691,086,336 (6,751 digits) (11:32)
19937 931,144,559,095,633,...,434,790,271,942,656 (12,003 digits) (1:22:32)
</pre>
=== cheating ===
{{trans|Picat}}
<syntaxhighlight lang="phix">
include mpfr.e
atom t0 = time()
mpz n = mpz_init(), m = mpz_init()
sequence validp = {2, 3, 5, 7, 13, 17, 19, 31, 61, 89, 107, 127, 521, 607,
1279, 2203, 2281, 3217, 4253, 4423, 9689, 9941, 11213,
19937, 21701, 23209, 44497, 86243, 110503, 132049, 216091,
756839, 859433, 1257787, 1398269, 2976221, 3021377, 6972593,
13466917, 20996011, 24036583, 25964951, 30402457, 32582657,
37156667, 42643801, 43112609, 57885161,
74207281, 77232917, 82589933}
if platform()=JS then validp = validp[1..35] end if -- (keep it under 5s)
for p in validp do
mpz_ui_pow_ui(n, 2, p)
mpz_sub_ui(n, n, 1)
mpz_ui_pow_ui(m, 2, p-1)
mpz_mul(n, n, m)
string ns = mpz_get_short_str(n,comma_fill:=true),
et = elapsed_short(time()-t0,5,"(%s)")
printf(1, "%d %s %s\n",{p,ns,et})
end for
?elapsed(time()-t0)
</syntaxhighlight>
<pre>
2 6
3 28
5 496
7 8,128
13 33,550,336
17 8,589,869,056
19 137,438,691,328
31 2,305,843,008,139,952,128
61 2,658,455,991,569,831,744,654,692,615,953,842,176
89 191,561,942,608,236,...,997,321,548,169,216 (54 digits)
107 13,164,036,458,569,6...,943,117,783,728,128 (65 digits)
127 14,474,011,154,664,5...,349,131,199,152,128 (77 digits)
521 23,562,723,457,267,3...,492,160,555,646,976 (314 digits)
607 141,053,783,706,712,...,570,759,537,328,128 (366 digits)
1279 54,162,526,284,365,8...,345,764,984,291,328 (770 digits)
2203 1,089,258,355,057,82...,580,834,453,782,528 (1,327 digits)
2281 99,497,054,337,086,4...,375,675,139,915,776 (1,373 digits)
3217 33,570,832,131,986,7...,888,332,628,525,056 (1,937 digits)
4253 18,201,749,040,140,4...,848,437,133,377,536 (2,561 digits)
4423 40,767,271,711,094,4...,020,642,912,534,528 (2,663 digits)
9689 11,434,731,753,038,6...,982,558,429,577,216 (5,834 digits)
9941 598,885,496,387,336,...,478,324,073,496,576 (5,985 digits)
11213 3,959,613,212,817,94...,255,702,691,086,336 (6,751 digits)
19937 931,144,559,095,633,...,434,790,271,942,656 (12,003 digits)
21701 1,006,564,970,546,40...,865,255,141,605,376 (13,066 digits)
23209 81,153,776,582,351,0...,048,603,941,666,816 (13,973 digits)
44497 365,093,519,915,713,...,965,353,031,827,456 (26,790 digits)
86243 144,145,836,177,303,...,480,957,360,406,528 (51,924 digits)
110503 13,620,458,213,388,4...,255,233,603,862,528 (66,530 digits)
132049 13,145,129,545,436,9...,438,491,774,550,016 (79,502 digits)
216091 27,832,745,922,032,7...,263,416,840,880,128 (130,100 digits)
756839 15,161,657,022,027,0...,971,600,565,731,328 (455,663 digits)
859433 83,848,822,675,015,7...,651,540,416,167,936 (517,430 digits)
1257787 849,732,889,343,651,...,394,028,118,704,128 (757,263 digits)
1398269 331,882,354,881,177,...,668,017,723,375,616 (841,842 digits)
2976221 194,276,425,328,791,...,106,724,174,462,976 (1,791,864 digits)
3021377 811,686,848,628,049,...,147,573,022,457,856 (1,819,050 digits)
6972593 9,551,760,305,212,09...,914,475,123,572,736 (4,197,919 digits)
13466917 42,776,415,902,185,6...,230,460,863,021,056 (8,107,892 digits)
20996011 7,935,089,093,651,70...,903,578,206,896,128 (12,640,858 digits)
24036583 44,823,302,617,990,8...,680,460,572,950,528 (14,471,465 digits) (5s)
25964951 7,462,098,419,004,44...,245,874,791,088,128 (15,632,458 digits) (8s)
30402457 49,743,776,545,907,0...,934,536,164,704,256 (18,304,103 digits) (10s)
32582657 77,594,685,533,649,8...,428,476,577,120,256 (19,616,714 digits) (13s)
37156667 20,453,422,553,410,5...,147,975,074,480,128 (22,370,543 digits) (16s)
42643801 1,442,850,579,600,99...,314,837,377,253,376 (25,674,127 digits) (20s)
43112609 50,076,715,684,982,3...,909,221,145,378,816 (25,956,377 digits) (24s)
57885161 169,296,395,301,618,...,179,626,270,130,176 (34,850,340 digits) (29s)
74207281 45,112,996,270,669,0...,008,557,930,315,776 (44,677,235 digits) (36s)
77232917 10,920,015,213,433,6...,001,402,016,301,056 (46,498,850 digits) (43s)
82589933 1,108,477,798,641,48...,798,007,191,207,936 (49,724,095 digits) (50s)
"50.6s"
</pre>
=={{header|PHP}}==
{{trans|C++}}
<
{
$sum = 0;
Line 2,898 ⟶ 3,233:
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:
<syntaxhighlight lang="picat">go =>
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].</syntaxhighlight>
{{out}}
<pre>perfect1 = [1,6,28,496,8128]</pre>
===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.
<syntaxhighlight lang="picat">go2 =>
println("Using the formula: 2^(p-1)*(2^p-1) for prime p"),
foreach(P in primes(32))
PF=perfectf(P),
% Check that it is really a perfect number
if perfect2(PF) then
printf("%w (prime %w)\n",PF,P)
end
end,
nl.
% Formula for perfect number candidates:
% 2^(p-1)*(2^p-1) where p is a prime
%
perfectf(P) = (2**(P-1))*((2**P)-1).
% Faster check of a perfect number
perfect2(N) => sum_divisors(N) == N.
% Sum of divisors
table
sum_divisors(N) = Sum =>
sum_divisors(2,N,1,Sum).
sum_divisors(I,N,Sum0,Sum), I > floor(sqrt(N)) =>
Sum = Sum0.
% I is a divisor of N
sum_divisors(I,N,Sum0,Sum), N mod I == 0 =>
Sum1 = Sum0 + I,
(I != N div I ->
Sum2 = Sum1 + N div I
;
Sum2 = Sum1
),
sum_divisors(I+1,N,Sum2,Sum).
% I is not a divisor of N.
sum_divisors(I,N,Sum0,Sum) =>
sum_divisors(I+1,N,Sum0,Sum).</syntaxhighlight>
{{out}}
<pre>6 (prime 2)
28 (prime 3)
496 (prime 5)
8128 (prime 7)
33550336 (prime 13)
8589869056 (prime 17)
137438691328 (prime 19)
2305843008139952128 (prime 31)
CPU time 118.039 seconds. Backtracks: 0</pre>
===Using list of the primes generating the perfect numbers===
Now let's cheat a little. At https://en.wikipedia.org/wiki/Perfect_number there is a list of the first 48 primes that generates perfect numbers according to the formula 2^(p-1)*(2^p-1) for prime p.
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.)
<syntaxhighlight lang="picat">go3 =>
ValidP = [2, 3, 5, 7, 13, 17, 19, 31, 61, 89, 107, 127, 521, 607,
1279, 2203, 2281, 3217, 4253, 4423, 9689, 9941, 11213,
19937, 21701, 23209, 44497, 86243, 110503, 132049, 216091,
756839, 859433, 1257787, 1398269, 2976221, 3021377, 6972593,
13466917, 20996011, 24036583, 25964951, 30402457, 32582657,
37156667, 42643801, 43112609, 57885161],
foreach(P in ValidP)
printf("prime %w: ", P),
PF = perfectf(P),
Len = PF.to_string.len,
if Len < 80 then
println(PF)
else
println(len=Len)
end,
if Len >= 100_000 then
fail
end
end,
nl.</syntaxhighlight>
{{out}}
<pre>prime 2: 6
prime 3: 28
prime 5: 496
prime 7: 8128
prime 13: 33550336
prime 17: 8589869056
prime 19: 137438691328
prime 31: 2305843008139952128
prime 61: 2658455991569831744654692615953842176
prime 89: 191561942608236107294793378084303638130997321548169216
prime 107: 13164036458569648337239753460458722910223472318386943117783728128
prime 127: 14474011154664524427946373126085988481573677491474835889066354349131199152128
prime 521: len = 314
prime 607: len = 366
prime 1279: len = 770
prime 2203: len = 1327
prime 2281: len = 1373
prime 3217: len = 1937
prime 4253: len = 2561
prime 4423: len = 2663
prime 9689: len = 5834
prime 9941: len = 5985
prime 11213: len = 6751
prime 19937: len = 12003
prime 21701: len = 13066
prime 23209: len = 13973
prime 44497: len = 26790
prime 86243: len = 51924
prime 110503: len = 66530
prime 132049: len = 79502
prime 216091: len = 130100</pre>
=={{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 2,913 ⟶ 3,376:
(=0 (% N I))
(inc 'C (+ (/ N I) I)) ) )
(= C N) ) )</
=={{header|PL/I}}==
<
declare n fixed;
declare sum fixed;
Line 2,926 ⟶ 3,389:
end;
return (sum=n);
end perfect;</
==={{header|PL/I-80}}===
<
%replace
Line 2,970 ⟶ 3,433:
end isperfect;
end perfect_search;</
{{out}}
Line 2,980 ⟶ 3,443:
8128
4 perfect numbers were found
</pre>
=={{header|PL/M}}==
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)
<syntaxhighlight lang="pli">100H: /* FIND SOME PERFECT NUMBERS: NUMBERS EQUAL TO THE SUM OF THEIR PROPER */
/* DIVISORS */
/* CP/M SYSTEM CALL AND I/O ROUTINES */
BDOS: PROCEDURE( FN, ARG ); /* CP/M BDOS SYSTEM CALL */
DECLARE FN BYTE, ARG ADDRESS;
GOTO 5;
END BDOS;
PR$CHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END;
PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END;
PR$NL: PROCEDURE; CALL PR$CHAR( 0DH ); CALL PR$CHAR( 0AH ); END;
PR$NUMBER: PROCEDURE( N );
DECLARE N ADDRESS;
DECLARE V ADDRESS, N$STR( 6 ) BYTE, W BYTE;
V = N;
W = LAST( N$STR );
N$STR( W ) = '$';
N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
DO WHILE( ( V := V / 10 ) > 0 );
N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
END;
CALL PR$STRING( .N$STR( W ) );
END PR$NUMBER;
/* TASK */
/* RETURNS TRUE IF N IS PERFECT, 0 OTHERWISE */
IS$PERFECT: PROCEDURE( N )BYTE;
DECLARE N ADDRESS;
DECLARE ( F1, F2, SUM ) ADDRESS;
SUM = 1;
F1 = 2;
F2 = N;
DO WHILE( F1 * F1 <= N );
IF N MOD F1 = 0 THEN DO;
SUM = SUM + F1;
F2 = N / F1;
/* AVOID COUNTING E.G., 2 TWICE AS A FACTOR OF 4 */
IF F2 > F1 THEN SUM = SUM + F2;
END;
F1 = F1 + 1;
END;
RETURN SUM = N;
END IS$PERFECT ;
/* TEST IS$PERFECT */
DECLARE N ADDRESS;
DO N = 2 TO 10$000;
IF IS$PERFECT( N ) THEN DO;
CALL PR$CHAR( ' ' );
CALL PR$NUMBER( N );
END;
END;
EOF</syntaxhighlight>
{{out}}
<pre>
6 28 496 8128
</pre>
Alternative, much faster version.
{{Trans|Action!}}
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)
<syntaxhighlight lang="pli">100H: /* FIND SOME PERFECT NUMBERS: NUMBERS EQUAL TO THE SUM OF THEIR PROPER */
/* DIVISORS */
/* CP/M SYSTEM CALL AND I/O ROUTINES */
BDOS: PROCEDURE( FN, ARG ); /* CP/M BDOS SYSTEM CALL */
DECLARE FN BYTE, ARG ADDRESS;
GOTO 5;
END BDOS;
PR$CHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END;
PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END;
PR$NL: PROCEDURE; CALL PR$CHAR( 0DH ); CALL PR$CHAR( 0AH ); END;
PR$NUMBER: PROCEDURE( N );
DECLARE N ADDRESS;
DECLARE V ADDRESS, N$STR( 6 ) BYTE, W BYTE;
V = N;
W = LAST( N$STR );
N$STR( W ) = '$';
N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
DO WHILE( ( V := V / 10 ) > 0 );
N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
END;
CALL PR$STRING( .N$STR( W ) );
END PR$NUMBER;
/* TASK - TRANSLATION OF ACTION! */
DECLARE MAX$NUM LITERALLY '10$000';
DECLARE PDS( 10$001 ) ADDRESS;
DECLARE ( I, J ) ADDRESS;
DO I = 2 TO MAX$NUM;
PDS( I ) = 1;
END;
DO I = 2 TO MAX$NUM;
DO J = I + I TO MAX$NUM BY I;
PDS( J ) = PDS( J ) + I;
END;
END;
DO I = 2 TO MAX$NUM;
IF PDS( I ) = I THEN DO;
CALL PR$NUMBER( I );
CALL PR$NL;
END;
END;
EOF</syntaxhighlight>
{{out}}
<pre>
6
28
496
8128
</pre>
=={{header|PowerShell}}==
<
{
$sum=0
Line 2,996 ⟶ 3,572:
}
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,014 ⟶ 3,590:
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,045 ⟶ 3,621:
N mod D =\= 0,
D2 is D + A, prime(N, D2, As).
</syntaxhighlight>
{{out}}
<pre>
Line 3,058 ⟶ 3,634:
===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,094 ⟶ 3,670:
%% 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,109 ⟶ 3,685:
EndIf
ProcedureReturn result
EndProcedure</
=={{header|Python}}==
Line 3,138 ⟶ 3,714:
===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,167 ⟶ 3,743:
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,213 ⟶ 3,789:
if __name__ == '__main__':
main()</
{{Out}}
<pre>[6, 28, 496, 8128]</pre>
Line 3,221 ⟶ 3,797:
<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,228 ⟶ 3,804:
10000 times
[ i^ 1+ perfect if [ i^ 1+ echo cr ] ]
</syntaxhighlight>
{{out}}
Line 3,240 ⟶ 3,816:
=={{header|R}}==
<
if (n==0|n==1) return(FALSE)
s <- seq (1,n-1)
Line 3,250 ⟶ 3,826:
# Usage - Warning High Memory Usage
is.perf(28)
sapply(c(6,28,496,8128,33550336),is.perf)</
=={{header|Racket}}==
<
(require math)
Line 3,263 ⟶ 3,839:
; 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,281 ⟶ 3,857:
}
.put for @perfects[^12];</
{{out}}
Line 3,298 ⟶ 3,874:
=={{header|REBOL}}==
<
sum: 0
repeat i (n - 1) [
Line 3,306 ⟶ 3,882:
]
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,322 ⟶ 3,898:
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,334 ⟶ 3,910:
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,350 ⟶ 3,926:
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,360 ⟶ 3,936:
:::* 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,380 ⟶ 3,956:
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,395 ⟶ 3,971:
===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,422 ⟶ 3,998:
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,455 ⟶ 4,031:
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,492 ⟶ 4,068:
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,502 ⟶ 4,078:
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,548 ⟶ 4,124:
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,564 ⟶ 4,140:
if sum = n return 1 else return 0 ok
return sum
</syntaxhighlight>
=={{header|RPL}}==
≪ 0 SWAP 1
'''WHILE''' DUP2 > '''REPEAT'''
'''IF''' DUP2 MOD NOT '''THEN''' ROT OVER + ROT ROT '''END'''
1 + '''END'''
DROP ==
≫ ''''PFCT?'''' STO
≪
{ } 1 1000 '''FOR''' n
'''IF''' n '''PFCT?''' '''THEN''' n + '''END''' '''NEXT'''
≫ ''''TASK'''' STO
{{out}}
<pre>
1: { 6 28 496 }
</pre>
A vintage HP-28S needs 157 seconds to collect all perfect numbers under 100...
=={{header|Ruby}}==
<
sum = 0
for i in 1...n
Line 3,573 ⟶ 4,167:
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,585 ⟶ 4,179:
end
divisors.uniq.inject(:+) == 2*n
end</
Test:
<
puts n if perf(n)
end</
{{out}}
<pre>
Line 3,599 ⟶ 4,193:
===Fast (Lucas-Lehmer)===
Generate and memoize perfect numbers as needed.
<
def mersenne_prime_pow?(p)
Line 3,623 ⟶ 4,217:
p perfect?(13164036458569648337239753460458722910223472318386943117783728128)
p Time.now - t1
</syntaxhighlight>
{{out}}
<pre>
Line 3,633 ⟶ 4,227:
=={{header|Run BASIC}}==
<
if perf(i) then print i;" ";
next i
Line 3,642 ⟶ 4,236:
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,669 ⟶ 4,263:
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,680 ⟶ 4,274:
|| we can write the list of all perfect numbers as
perfects = { n <- 1... ; n = sum(factors n) }
</syntaxhighlight>
=={{header|S-BASIC}}==
<
$lines
Line 3,708 ⟶ 4,302:
rem - exercise the function
var k, found = integer
print "Searching up to"; search_limit; " for perfect numbers ..."
found = 0
for k = 2 to search_limit
if isperfect(k) then
begin
print k
found = found + 1
end
next k
print found; "
end
</syntaxhighlight>
{{out}}
<pre>
Searching up to
6
28
496
8128
4 were found
</pre>
=={{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,745 ⟶ 4,346:
(loop (+ i 1) (+ sum i)))
(else
(loop (+ i 1) sum)))))</
=={{header|Seed7}}==
<
const func boolean: isPerfect (in integer: n) is func
Line 3,779 ⟶ 4,380:
end if;
end for;
end func;</
{{Out}}
<pre>
Line 3,790 ⟶ 4,391:
=={{header|Sidef}}==
<
n.sigma == 2*n
}
Line 3,796 ⟶ 4,397:
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 3,812 ⟶ 4,413:
for n in (1..10000) {
say n if is_even_perfect(n)
}</
{{out}}
Line 3,823 ⟶ 4,424:
=={{header|Simula}}==
<
BEGIN
INTEGER SUM;
Line 3,830 ⟶ 4,431:
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 3,860 ⟶ 4,461:
inject: 1 into: [ :a :b | a + b ] ) = self
]
].</
<
=={{header|SparForte}}==
As a structured script.
<syntaxhighlight lang="ada">#!/usr/local/bin/spar
pragma annotate( summary, "perfect" );
pragma annotate( description, "In mathematics, a perfect number is a positive integer" );
pragma annotate( description, "that is the sum of its proper positive divisors, that is," );
pragma annotate( description, "the sum of the positive divisors excluding the number" );
pragma annotate( description, "itself." );
pragma annotate( see_also, "http://en.wikipedia.org/wiki/Perfect_number" );
pragma annotate( author, "Ken O. Burtch" );
pragma license( unrestricted );
pragma restriction( no_external_commands );
procedure perfect is
function is_perfect( n : positive ) return boolean is
total : natural := 0;
begin
for i in 1..n-1 loop
if n mod i = 0 then
total := @+i;
end if;
end loop;
return total = natural( n );
end is_perfect;
number : positive;
result : boolean;
begin
number := 6;
result := is_perfect( number );
put( number ) @ ( " : " ) @ ( result );
new_line;
number := 18;
result := is_perfect( number );
put( number ) @ ( " : " ) @ ( result );
new_line;
number := 28;
result := is_perfect( number );
put( number ) @ ( " : " ) @ ( result );
new_line;
end perfect;</syntaxhighlight>
=={{header|Swift}}==
{{trans|Java}}
<
var sum = 0
for i in 1..<n {
Line 3,880 ⟶ 4,528:
println(i)
}
}</
{{out}}
<pre>
Line 3,890 ⟶ 4,538:
=={{header|Tcl}}==
<
set sum 0
for {set i 1} {$i <= $n} {incr i} {
Line 3,896 ⟶ 4,544:
}
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 3,914 ⟶ 4,562:
{{trans|Phix}}
Using [[Factors_of_an_integer#VBA]], slightly adapted.
<
Application.Volatile
Dim i As Long
Line 3,942 ⟶ 4,590:
If is_perfect(i) Then Debug.Print i
Next i
End Sub</
<pre> 6
28
Line 3,949 ⟶ 4,597:
=={{header|VBScript}}==
<
IsPerfect = False
i = n - 1
Line 3,965 ⟶ 4,613:
WScript.StdOut.Write IsPerfect(CInt(WScript.Arguments(0)))
WScript.StdOut.WriteLine</
{{out}}
Line 3,976 ⟶ 4,624:
C:\>
</pre>
=={{header|V (Vlang)}}==
{{trans|go}}
<syntaxhighlight lang="v (vlang)">fn compute_perfect(n i64) bool {
mut sum := i64(0)
for i := i64(1); i < n; i++ {
if n%i == 0 {
sum += i
}
}
return sum == n
}
// following fntion satisfies the task, returning true for all
// perfect numbers representable in the argument type
fn is_perfect(n i64) bool {
return n in [i64(6), 28, 496, 8128, 33550336, 8589869056,
137438691328, 2305843008139952128]
}
// validation
fn main() {
for n := i64(1); ; n++ {
if is_perfect(n) != compute_perfect(n) {
panic("bug")
}
if n%i64(1e3) == 0 {
println("tested $n")
}
}
}</syntaxhighlight>
{{Out}}
<pre>
tested 1000
tested 2000
tested 3000
...
</pre>
Line 3,982 ⟶ 4,669:
{{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,005 ⟶ 4,692:
i = i + 2 // there are no known odd perfect numbers
}
System.print()</
{{out}}
Line 4,015 ⟶ 4,702:
{{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,044 ⟶ 4,731:
p = p + 1
}
System.print()</
{{out}}
Line 4,052 ⟶ 4,739:
=={{header|XPL0}}==
<
func Perfect(N); \Return 'true' if N is a perfect number
Line 4,069 ⟶ 4,756:
if Perfect(N) then [IntOut(0, N); CrLf(0)];
];
]</
{{out}}
Line 4,083 ⟶ 4,770:
=={{header|Yabasic}}==
{{trans|True BASIC}}
<
sub isPerfect(n)
if (n < 2) or mod(n, 2) = 1 then return false : endif
Line 4,100 ⟶ 4,787:
print
end
</syntaxhighlight>
=={{header|Zig}}==
<syntaxhighlight lang="zig">
const std = @import("std");
const expect = std.testing.expect;
Line 4,134 ⟶ 4,821:
expect(propersum(30) == 42);
}
</syntaxhighlight>
{{Out}}
<pre>
Line 4,141 ⟶ 4,828:
=={{header|zkl}}==
{{trans|D}}
<
{ n == [1..n-1].filter('wrap(i){ n % i == 0 }).sum(); }</
{{out}}
<pre>
|