Multiplicatively perfect numbers: Difference between revisions

Added Easylang
(Added a note to make the inclusion of '1' as a MPN optional.)
(Added Easylang)
 
(25 intermediate revisions by 11 users not shown)
Line 17:
* The OEIS sequence:  [[oeis:A007422|A007422: Multiplicatively perfect numbers]] 
<br><br>
 
=={{header|ALGOL 68}}==
{{libheader|ALGOL 68-primes}}
Uses sieves, counts 1 as a multiplicatively perfect number.<br>
As with the Phix and probably other samples, uses the fact that the multiplicatively perfect numbers (other than 1) must have three proper divisors - see OIES A007422.
<syntaxhighlight lang="algol68">
BEGIN # find multiplicatively perfect numbers - numbers whose proper #
# divisor product is the number itself ( includes 1 ) #
PR read "primes.incl.a68" PR # include prime utilties #
INT max number = 500 000; # largest number we wlil consider #
[]BOOL prime = PRIMESIEVE max number; # sieve the primes to max number #
[ 1 : max number ]INT pdc; # table of proper divisor counts #
[ 1 : max number ]INT pfc; # table of prime factor counts #
# count the proper divisors and prime factors #
FOR n TO UPB pdc DO pdc[ n ] := 1; pfc[ n ] := 0 OD;
FOR i FROM 2 TO UPB pdc DO
BOOL is prime = prime[ i ];
INT m := 1; # j will be the mth multiple of i #
FOR j FROM i + i BY i TO UPB pdc DO
pdc[ j ] +:= 1;
IF prime[ m +:= 1 ] THEN # j is a prime multiple of i #
pfc[ j ] +:= 1;
IF i = m THEN # j is i squared #
pfc[ j ] +:= 1
FI
ELSE # j is not a prime multiple of i #
pfc[ j ] +:= pfc[ m ] # add the prime factor count of m #
FI
OD
OD;
# find the mutiplicatively perfect numbers #
INT mp count := 0;
INT sp count := 0;
INT next to show := 500;
FOR n TO UPB pdc DO
IF n = 1 OR pdc[ n ] = 3 THEN
# n is 1 or has 3 proper divisors so is multiplicatively perfect #
# number - see OEIS A007422 #
mp count +:= 1;
IF n < 500 THEN
print( ( " ", whole( n, -3 ) ) );
IF mp count MOD 10 = 0 THEN print( ( newline ) ) FI
FI
FI;
IF pfc[ n ] = 2 THEN
# 2 prime factors, n is semi-prime #
sp count +:= 1
FI;
IF n = next to show THEN
print( ( "Up to ", whole( next to show, -8 )
, " there are ", whole( mp count, -6 )
, " multiplicatively perfect numbers and ", whole( sp count, -6 )
, " semi-primes", newline
)
);
next to show *:= 10
FI
OD
END
</syntaxhighlight>
{{out}}
<pre>
1 6 8 10 14 15 21 22 26 27
33 34 35 38 39 46 51 55 57 58
62 65 69 74 77 82 85 86 87 91
93 94 95 106 111 115 118 119 122 123
125 129 133 134 141 142 143 145 146 155
158 159 161 166 177 178 183 185 187 194
201 202 203 205 206 209 213 214 215 217
218 219 221 226 235 237 247 249 253 254
259 262 265 267 274 278 287 291 295 298
299 301 302 303 305 309 314 319 321 323
326 327 329 334 335 339 341 343 346 355
358 362 365 371 377 381 382 386 391 393
394 395 398 403 407 411 413 415 417 422
427 437 445 446 447 451 453 454 458 466
469 471 473 478 481 482 485 489 493 497
Up to 500 there are 150 multiplicatively perfect numbers and 153 semi-primes
Up to 5000 there are 1354 multiplicatively perfect numbers and 1365 semi-primes
Up to 50000 there are 12074 multiplicatively perfect numbers and 12110 semi-primes
Up to 500000 there are 108223 multiplicatively perfect numbers and 108326 semi-primes
</pre>
 
=={{header|BASIC}}==
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vb">arraybase 1
limit = 500
dim Divisors(1)
c = 0
 
print "Special numbers under "; limit; ":"
 
for n = 1 to limit
pro = 1
for m = 2 to ceil(n / 2)
if n mod m = 0 then
pro *= m
c += 1
redim Divisors(c)
Divisors[c] = m
end if
next m
ub = Divisors[?]
if n = pro and ub > 2 then
print rjust(string(n), 3); " = "; rjust(string(Divisors[ub-1]), 2); " x "; rjust(string(Divisors[ub]), 3)
end if
next n</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|True BASIC}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="qbasic">LET limit = 50
DIM divisors(0)
LET c = 1
 
PRINT "Special numbers under"; limit; ":"
 
FOR n = 1 TO limit
LET pro = 1
FOR m = 2 TO ceil(n/2)
IF remainder(n, m) = 0 THEN
LET pro = pro*m
MAT REDIM divisors(c)
LET divisors(c) = m
LET c = c+1
END IF
NEXT m
LET ub = UBOUND(divisors)
IF n = pro AND ub > 1 THEN PRINT USING "### = ## x ###": n, divisors(ub-1), divisors(ub)
NEXT n
END</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|PureBasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vb">Macro Ceil (_x_)
Round(_x_, #PB_Round_Up)
EndMacro
 
OpenConsole()
Define.i limit = 500
Dim Divisors.i(1)
Define.i n, pro, m, c = 0, ub
 
PrintN("Special numbers under" + Str(limit) + ":")
 
For n = 1 To limit
pro = 1
For m = 2 To Ceil(n / 2)
If Mod(n, m) = 0:
pro * m
ReDim Divisors(c) : Divisors(c) = m
c + 1
EndIf
Next m
ub = ArraySize(Divisors())
If n = pro And ub > 1:
PrintN(RSet(Str(n),3) + " = " + RSet(Str(Divisors(ub-1)),2) + " x " + RSet(Str(Divisors(ub)),3))
EndIf
Next n
Input()
CloseConsole()</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|Yabasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vb">limit = 500
dim Divisors(1)
c = 1
 
print "Special numbers under", limit, ":"
 
for n = 1 to limit
pro = 1
for m = 2 to ceil(n / 2)
if mod(n, m) = 0 then
pro = pro * m
dim Divisors(c) : Divisors(c) = m
c = c + 1
fi
next m
ub = arraysize(Divisors(), 1)
if n = pro and ub > 1 then
print n using "###", " = ", Divisors(ub-1) using "##", " x ", Divisors(ub) using "###"
fi
next n</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
=={{header|C}}==
This includes '1' as an MPN. Run time around 2.3 seconds.
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdbool.h>
Line 38 ⟶ 231:
 
void divisors(int n, int *divs, int *length) {
if (n < 1) {
*length = 0;
return;
}
int i, j, k = 1, c = 0;
if (n%2) k = 2;
Line 48 ⟶ 237:
if (!(n%i)) {
divs[c++] = i;
if (c > 2) break; // not eligible if has > 2 divisors
j = n / i;
if (j != i) divs[c++] = j;
Line 57 ⟶ 247:
int main() {
int i, d, j, k, t, length, prod;
int divs[2004], count = 0, limit = 500, s = 3, c = 3, squares = 1, cubes = 1;
printf("Multiplicatively perfect numbers under %d:\n", limit);
setlocale(LC_NUMERIC, "");
for (i = 01; ; ++i) {
divisorsif (i, divs,!= &length1); {
if divisors(lengthi, >divs, 1&length) {;
} else prod = 1;{
for (ddivs[1] = divs[0;] d < length; ++d) prod *= divs[d]1;
if (prodlength == i) {2;
++count;}
if (length == 2 && divs[0] * divs[1] if== (i < 500) {
printf("%3d ", i)++count;
if (i < if (!(count%10)500) printf("\n");{
}printf("%3d ", i);
if (!(count%10)) printf("\n");
}
}
if (i == 499) printf("\n\n");
if (i >= limit - 1) {
for (j = s; j * j < limit; j += 2) if (isPrime(j)) ++squares;
for (k = c; k * k * k < limit; k +=2 ) if (isPrime(k)) ++cubes;
t = count + squares - cubes - 1;
printf("Counts under %'7d9d: MPNs = %'7d Semi-primes = %'7d\n", limit, count, t);
if (limit == 5000005000000) break;
s = j;
c = k;
Line 91 ⟶ 282:
<pre>
Multiplicatively perfect numbers under 500:
1 6 8 10 14 15 21 22 26 27 33
33 34 35 38 39 46 51 55 57 58 62
62 65 69 74 77 82 85 86 87 91 93
93 94 95 106 111 115 118 119 122 123 125
125 129 133 134 141 142 143 145 146 155 158
158 159 161 166 177 178 183 185 187 194 201
201 202 203 205 206 209 213 214 215 217 218
218 219 221 226 235 237 247 249 253 254 259
259 262 265 267 274 278 287 291 295 298 299
299 301 302 303 305 309 314 319 321 323 326
326 327 329 334 335 339 341 343 346 355 358
358 362 365 371 377 381 382 386 391 393 394
394 395 398 403 407 411 413 415 417 422 427
427 437 445 446 447 451 453 454 458 466 469
469 471 473 478 481 482 485 489 493 497
 
Counts under 500: MPNs = 149150 Semi-primes = 153
Counts under 5,000: MPNs = 1,353354 Semi-primes = 1,365
Counts under 50,000: MPNs = 12,073074 Semi-primes = 12,110
Counts under 500,000: MPNs = 108,222223 Semi-primes = 108,326
Counts under 5,000,000: MPNs = 978,983 Semi-primes = 979,274
</pre>
 
=={{header|C++}}==
<syntaxhighlight lang=C++>#include <iostream>
#include <vector>
#include <numeric>
 
std::vector<int> divisors( int n ) {
std::vector<int> divisors ;
for ( int i = 1 ; i < n + 1 ; i++ ) {
if ( n % i == 0 )
divisors.push_back( i ) ;
}
return divisors ;
}
 
int main( ) {
std::vector<int> multi_perfect ;
for ( int i = 1 ; i < 501 ; i++ ) {
std::vector<int> divis { divisors( i ) } ;
if ( std::accumulate( divis.begin( ) , divis.end( ) , 1 ,
std::multiplies<int>() ) == (i * i ) )
multi_perfect.push_back( i ) ;
}
std::cout << '(' ;
int count = 1 ;
for ( int i : multi_perfect ) {
std::cout << i << ' ' ;
if ( count % 15 == 0 )
std::cout << '\n' ;
count++ ;
}
std::cout << ")\n" ;
return 0 ;
}</syntaxhighlight>
{{out}}
<pre>
(1 6 8 10 14 15 21 22 26 27 33 34 35 38 39
46 51 55 57 58 62 65 69 74 77 82 85 86 87 91
93 94 95 106 111 115 118 119 122 123 125 129 133 134 141
142 143 145 146 155 158 159 161 166 177 178 183 185 187 194
201 202 203 205 206 209 213 214 215 217 218 219 221 226 235
237 247 249 253 254 259 262 265 267 274 278 287 291 295 298
299 301 302 303 305 309 314 319 321 323 326 327 329 334 335
339 341 343 346 355 358 362 365 371 377 381 382 386 391 393
394 395 398 403 407 411 413 415 417 422 427 437 445 446 447
451 453 454 458 466 469 471 473 478 481 482 485 489 493 497
)
</pre>
 
=={{header|EasyLang}}==
<syntaxhighlight>
for n = 1 to 500
pro = 1
for m = 2 to n div 2
if n mod m = 0
pro *= m
.
.
if n = pro
write n & " "
.
.
</syntaxhighlight>
{{out}}
<pre>
1 6 8 10 14 15 21 22 26 27 33 34 35 38 39 46 51 55 57 58 62 65 69 74 77 82 85 86 87 91 93 94 95 106 111 115 118 119 122 123 125 129 133 134 141 142 143 145 146 155 158 159 161 166 177 178 183 185 187 194 201 202 203 205 206 209 213 214 215 217 218 219 221 226 235 237 247 249 253 254 259 262 265 267 274 278 287 291 295 298 299 301 302 303 305 309 314 319 321 323 326 327 329 334 335 339 341 343 346 355 358 362 365 371 377 381 382 386 391 393 394 395 398 403 407 411 413 415 417 422 427 437 445 446 447 451 453 454 458 466 469 471 473 478 481 482 485 489 493 497
</pre>
 
Line 137 ⟶ 396:
{{out}}
<pre>Similar to Ring entry.</pre>
 
=={{header|Go}}==
{{trans|C}}
{{libheader|Go-rcu}}
Run time around 9.2 seconds.
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"rcu"
)
 
// library method customized for this task
func Divisors(n int) []int {
var divisors []int
i := 1
k := 1
if n%2 == 1 {
k = 2
}
for ; i*i <= n; i += k {
if i > 1 && n%i == 0 { // exclude 1 and n
divisors = append(divisors, i)
if len(divisors) > 2 { // not eligible if has > 2 divisors
break
}
j := n / i
if j != i {
divisors = append(divisors, j)
}
}
}
return divisors
}
 
func main() {
count := 0
limit := 500
s := 3
c := 3
squares := 1
cubes := 1
fmt.Printf("Multiplicatively perfect numbers under %d:\n", limit)
var divs []int
for i := 0; ; i++ {
if i != 1 {
divs = Divisors(i)
} else {
divs = []int{1, 1}
}
if len(divs) == 2 && divs[0]*divs[1] == i {
count++
if i < 500 {
fmt.Printf("%3d ", i)
if count%10 == 0 {
fmt.Println()
}
}
}
if i == 499 {
fmt.Println()
}
if i >= limit-1 {
var j, k int
for j = s; j*j < limit; j += 2 {
if rcu.IsPrime(j) {
squares++
}
}
for k = c; k*k*k < limit; k += 2 {
if rcu.IsPrime(k) {
cubes++
}
}
t := count + squares - cubes - 1
slimit := rcu.Commatize(limit)
scount := rcu.Commatize(count)
st := rcu.Commatize(t)
fmt.Printf("Counts under %9s: MPNs = %7s Semi-primes = %7s\n", slimit, scount, st)
if limit == 5000000 {
break
}
s, c = j, k
limit *= 10
}
}
}</syntaxhighlight>
 
{{out}}
<pre>
Same as C example.
</pre>
 
=={{header|Haskell}}==
<syntaxhighlight lang=Haskell>
divisors :: Int -> [Int]
divisors n = [d | d <- [1..n] , mod n d == 0 ]
 
isMultiplicativelyPerfect :: Int -> Bool
isMultiplicativelyPerfect n = (product $ divisors n) == n ^ 2
 
solution :: [Int]
solution = filter isMultiplicativelyPerfect [1..500]
</syntaxhighlight>
{{out}}
<pre>
[1,6,8,10,14,15,21,22,26,27,33,34,35,38,39,46,51,55,57,58,62,65,69,74,77,82,85,86,87,91,93,94,95,106,111,115,118,119,122,123,125,129,133,134,141,142,143,145,146,155,158,159,161,166,177,178,183,185,187,194,201,202,203,205,206,209,213,214,215,217,218,219,221,226,235,237,247,249,253,254,259,262,265,267,274,278,287,291,295,298,299,301,302,303,305,309,314,319,321,323,326,327,329,334,335,339,341,343,346,355,358,362,365,371,377,381,382,386,391,393,394,395,398,403,407,411,413,415,417,422,427,437,445,446,447,451,453,454,458,466,469,471,473,478,481,482,485,489,493,497]
</pre>
 
=={{header|J}}==
Line 163 ⟶ 530:
For the stretch goal, we need to determine the number of semi-primes, given the number of multiplicatively perfect numbers less than N:
 
<syntaxhighlight lang=J>adjSemiPrime=: + _1 + %: -&(p:inv) 3&%:</syntaxhighlight>
 
Thus (first number in following results is count of multiplicatively perfect numbers, second is count of semiprimes):
 
<syntaxhighlight lang=J> {{ (, (adjSemiPrime &y)+]) +/isMPerfect i.y}} 500
150 153
{{ (, (adjSemiPrime &y)+]) +/isMPerfect i.y}} 5000
1354 1365
{{ (, (adjSemiPrime &y)+]) +/isMPerfect i.y}} 50000
12074 12110
{{ (, (adjSemiPrime &y)+]) +/isMPerfect i.y}} 500000
108223 108326</syntaxhighlight>
 
Line 246 ⟶ 613:
 
Counts under 500000: MPNs = 108222 Semi-primes = 108326
</pre>
 
=={{header|Nim}}==
In our solution, 1 is not considered to be a multiplicatively perfect number.
 
Using 32 bits integers rather than 64 bits integers improves considerably the performance. With a limit set to 5_000_000 and 64 bits integers, the program runs in around 10 seconds. This time drops to 3 seconds if 32 bits integers are used.
<syntaxhighlight lang="Nim">import std/strformat
 
func isMPN(n: int32): bool =
## Return true if "n" is a multiplicatively perfect number.
## We consider than 1 is not an MPN.
var first, second = 0i32 # First and second proper divisors.
let delta = 1 + (n and 1)
var d = delta + 1
while d * d <= n:
if n mod d == 0:
if second != 0: return false # More than two proper divisors.
first = d
let q = n div d
if q != d: second = q
inc d, delta
result = first * second == n
 
### Task ###
var count = 0
for n in 1i32..499i32:
if n.isMPN:
inc count
stdout.write &"{n:3}"
stdout.write if count mod 10 == 0: '\n' else: ' '
echo '\n'
 
### Stretch task ###
 
func isPrime(n: int32): bool =
## Return true if "n" is prime.
if n < 2: return false
if (n and 1) == 0: return n == 2
if n mod 3 == 0: return n == 3
var k = 5
var delta = 2
while k * k <= n:
if n mod k == 0: return false
inc k, delta
delta = 6 - delta
result = true
 
var mpnCount = 0
var limit = 500i32
var ns, nc = 3i32
var squares, cubes = 1i32
var n = 1i32
while true:
inc n
if n == limit:
while ns * ns < limit:
if ns.isPrime: inc squares
inc ns, 2
while nc * nc * nc < limit:
if nc.isPrime: inc cubes
inc nc, 2
echo &"Under {limit} there are {mpnCount} MPNs and {mpnCount - cubes + squares} semi-primes."
if limit == 500_000: break
limit *= 10
if n.isMPN: inc mpnCount
</syntaxhighlight>
 
{{out]]
<pre> 6 8 10 14 15 21 22 26 27 33
34 35 38 39 46 51 55 57 58 62
65 69 74 77 82 85 86 87 91 93
94 95 106 111 115 118 119 122 123 125
129 133 134 141 142 143 145 146 155 158
159 161 166 177 178 183 185 187 194 201
202 203 205 206 209 213 214 215 217 218
219 221 226 235 237 247 249 253 254 259
262 265 267 274 278 287 291 295 298 299
301 302 303 305 309 314 319 321 323 326
327 329 334 335 339 341 343 346 355 358
362 365 371 377 381 382 386 391 393 394
395 398 403 407 411 413 415 417 422 427
437 445 446 447 451 453 454 458 466 469
471 473 478 481 482 485 489 493 497
 
Under 500 there are 149 MPNs and 153 semi-primes.
Under 5000 there are 1353 MPNs and 1365 semi-primes.
Under 50000 there are 12073 MPNs and 12110 semi-primes.
Under 500000 there are 108222 MPNs and 108326 semi-primes.
</pre>
 
=={{header|Perl}}==
{{trans|Raku}}
{{libheader|ntheory}}
<syntaxhighlight lang="perl" line>
use v5.36;
use enum <false true>;
use ntheory <is_prime nth_prime is_semiprime gcd>;
 
sub comma { reverse ((reverse shift) =~ s/.{3}\K/,/gr) =~ s/^,//r }
sub table (@V) { my $t = 10 * (my $w = 5); ( sprintf( ('%'.$w.'d')x@V, @V) ) =~ s/.{1,$t}\K/\n/gr }
 
sub find_factor ($n, $constant = 1) { # NB: required that n > 1
my($x, $rho, $factor) = (2, 1, 1);
while ($factor == 1) {
$rho *= 2;
my $fixed = $x;
for (0..$rho) {
$x = ( $x * $x + $constant ) % $n;
$factor = gcd(($x-$fixed), $n);
last if 1 < $factor;
}
}
$factor = find_factor($n, $constant+1) if $n == $factor;
$factor
}
 
# Call with range 1..$limit
sub is_mpn($n) {
state $cube = 1; $cube = 1 if $n == 1; # set and reset
$n == 1 ? return true : is_prime($n) ? return false : ();
++$cube, return true if $n == nth_prime($cube)**3;
my $factor = find_factor($n);
my $div = int $n/$factor;
return true if is_prime $factor and is_prime $div and $div != $factor;
false
}
 
say "Multiplicatively perfect numbers less than 500:\n" . table grep is_mpn($_), 1..499;
 
say 'There are:';
for my $limit (5e2, 5e3, 5e4, 5e5, 5e6) {
my($m,$s) = (0,0);
is_mpn $_ and $m++ for 1..$limit-1;
is_semiprime $_ and $s++ for 1..$limit-1;
printf "%8s MPNs less than %8s, %8s semiprimes\n", comma($m), $limit, comma $s
}
</syntaxhighlight>
{{out}}
<pre>
Multiplicatively perfect numbers less than 500:
1 6 8 10 14 15 21 22 26 27
33 34 35 38 39 46 51 55 57 58
62 65 69 74 77 82 85 86 87 91
93 94 95 106 111 115 118 119 122 123
125 129 133 134 141 142 143 145 146 155
158 159 161 166 177 178 183 185 187 194
201 202 203 205 206 209 213 214 215 217
218 219 221 226 235 237 247 249 253 254
259 262 265 267 274 278 287 291 295 298
299 301 302 303 305 309 314 319 321 323
326 327 329 334 335 339 341 343 346 355
358 362 365 371 377 381 382 386 391 393
394 395 398 403 407 411 413 415 417 422
427 437 445 446 447 451 453 454 458 466
469 471 473 478 481 482 485 489 493 497
 
There are:
150 MPNs less than 500, 153 semiprimes
1,354 MPNs less than 5000, 1,365 semiprimes
12,074 MPNs less than 50000, 12,110 semiprimes
108,223 MPNs less than 500000, 108,326 semiprimes
978,983 MPNs less than 5000000, 979,274 semi primes
</pre>
 
=={{header|Phix}}==
Includes 1, to exclude just start with multiplicatively_perfect_numbers = 0 and r = {}.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">multiplicatively_perfect_numbers</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">01</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">semiprime_numbers</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">five_e_n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">5e2</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">5e55e6</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">pn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">vslice</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">prime_powers</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">product</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">))=</span><span style="color: #000000;">4</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">multiplicatively_perfect_numbers</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">500</span> <span style="color: #008080;">then</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">n</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">500</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d multiplicatively perfect numbers under 500: %s\n"</span><span style="color: #0000FF;">,</span>
<span style="color: #0000FF;">{</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">),</span><span style="color: #008000;">","</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pn</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span>
Line 269 ⟶ 795:
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">five_e_n</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8008080;">printfif</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1n</span><span style="color: #0000FF;">,=</span><span style="color: #008000000000;">"Counts under %,7d: MPNs = %,7d Semi-primes = %,7d\n"5e2</span> <span style="color: #0000FF008080;">,then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d multiplicatively perfect numbers under 500: %s\n"</span><span style="color: #0000FF;">,</span>
<span style="color: #0000FF;">{</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">),</span><span style="color: #008000;">","</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Counts under %,9d: MPNs = %,7d Semi-primes = %,7d\n"</span><span style="color: #0000FF;">,</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">five_e_n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">multiplicatively_perfect_numbers</span><span style="color: #0000FF;">,</span><span style="color: #000000;">semiprime_numbers</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">five_e_n</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">10</span>
Line 277 ⟶ 807:
{{out}}
<pre>
149150 multiplicatively perfect numbers under 500: 1,6,8,10,14,15,...,482,485,489,493,497
Counts under 500: MPNs = 149150 Semi-primes = 153
Counts under 5,000: MPNs = 1,353354 Semi-primes = 1,365
Counts under 50,000: MPNs = 12,073074 Semi-primes = 12,110
Counts under 500,000: MPNs = 108,222223 Semi-primes = 108,326
Counts under 5,000,000: MPNs = 978,983 Semi-primes = 979,274
</pre>
 
=={{header|PL/M}}==
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)
<syntaxhighlight lang="plm">
100H: /* FIND MUKTIPLICATIVELY PERFECT NUMBERS - NUMBERS WHOSE PROPER */
/* DIVISOR PRODUCT IS THE NUMBER ITSELF */
/* NOTE THIS IS EQUIVALENT TO FINDING NUMBERS WITH 3 PROPER DIVISORS */
/* SEE OEIS A007422 */
 
/* CP/M BDOS SYSTEM CALL */
BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END;
/* I/O ROUTINES */
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 ); /* PRINTS A NUMBER IN THE MINIMUN FIELD WIDTH */
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;
 
/* FIND THE NUMBERS UP TO 500 */
 
DECLARE PDC ( 501 )ADDRESS; /* TABLE OF PROPER DIVISOR COUNTS */
DECLARE ( I, J, COUNT ) ADDRESS;
 
/* COUNT THE PROPER DIVISORS OF NUMBERS TO 500 */
DO I = 0 TO LAST( PDC ); PDC( I ) = 1; END;
DO I = 2 TO LAST( PDC );
DO J = I + I TO LAST( PDC ) BY I;
PDC( J ) = PDC( J ) + 1;
END;
END;
PDC( 1 ) = 3; /* PRETEND 1 HAS 3 PROPER DIVISORS SO IT IS INCLUDED */
 
/* SHOW YHE MULTIPLICATIVELY PERFECT NUMBERS */
COUNT = 0;
DO I = 1 TO LAST( PDC );
IF PDC( I ) = 3 THEN DO;
CALL PR$CHAR( ' ' );
IF I < 100 THEN DO;
IF I < 10 THEN CALL PR$CHAR( ' ' );
CALL PR$CHAR( ' ' );
END;
CALL PR$NUMBER( I );
IF ( COUNT := COUNT + 1 ) MOD 10 = 0 THEN CALL PR$NL;
END;
END;
 
EOF
</syntaxhighlight>
{{out}}
<pre>
1 6 8 10 14 15 21 22 26 27
33 34 35 38 39 46 51 55 57 58
62 65 69 74 77 82 85 86 87 91
93 94 95 106 111 115 118 119 122 123
125 129 133 134 141 142 143 145 146 155
158 159 161 166 177 178 183 185 187 194
201 202 203 205 206 209 213 214 215 217
218 219 221 226 235 237 247 249 253 254
259 262 265 267 274 278 287 291 295 298
299 301 302 303 305 309 314 319 321 323
326 327 329 334 335 339 341 343 346 355
358 362 365 371 377 381 382 386 391 393
394 395 398 403 407 411 413 415 417 422
427 437 445 446 447 451 453 454 458 466
469 471 473 478 481 482 485 489 493 497
</pre>
 
=={{header|Raku}}==
 
<syntaxhighlight lang="raku" line>use List::Divvy;
use Lingua::EN::Numbers;
 
constant @primes = (^∞).grep: &is-prime;
constant @cubes = @primes.map: *³;
 
state $cube = 0;
sub is-mpn(Int $n ) {
return False if $n.is-prime;
if $n == @cubes[$cube] {
++$cube;
return True
}
my $factor = find-factor($n);
return True if ($factor.is-prime && ( my $div = $n div $factor ).is-prime && ($div != $factor));
False;
}
 
sub find-factor ( Int $n, $constant = 1 ) {
my $x = 2;
my $rho = 1;
my $factor = 1;
while $factor == 1 {
$rho *= 2;
my $fixed = $x;
for ^$rho {
$x = ( $x * $x + $constant ) % $n;
$factor = ( $x - $fixed ) gcd $n;
last if 1 < $factor;
}
}
$factor = find-factor( $n, $constant + 1 ) if $n == $factor;
$factor;
}
 
constant @mpn = lazy 1, |(2..*).grep: &is-mpn;
 
say 'Multiplicatively perfect numbers less than 500:';
put @mpn.&upto(500).batch(10)».fmt("%3d").join: "\n";
 
put "\nThere are:";
for 5e2, 5e3, 5e4, 5e5, 5e6 {
printf "%8s MPNs less than %9s, %7s semiprimes.\n",
comma(my $count = +@mpn.&upto($_)), .Int.&comma,
comma $count + @primes.map(*²).&upto($_) - @cubes.&upto($_) - 1;
}</syntaxhighlight>
{{out}}
<pre>Multiplicatively perfect numbers less than 500:
1 6 8 10 14 15 21 22 26 27
33 34 35 38 39 46 51 55 57 58
62 65 69 74 77 82 85 86 87 91
93 94 95 106 111 115 118 119 122 123
125 129 133 134 141 142 143 145 146 155
158 159 161 166 177 178 183 185 187 194
201 202 203 205 206 209 213 214 215 217
218 219 221 226 235 237 247 249 253 254
259 262 265 267 274 278 287 291 295 298
299 301 302 303 305 309 314 319 321 323
326 327 329 334 335 339 341 343 346 355
358 362 365 371 377 381 382 386 391 393
394 395 398 403 407 411 413 415 417 422
427 437 445 446 447 451 453 454 458 466
469 471 473 478 481 482 485 489 493 497
 
There are:
150 MPNs less than 500, 153 semiprimes.
1,354 MPNs less than 5,000, 1,365 semiprimes.
12,074 MPNs less than 50,000, 12,110 semiprimes.
108,223 MPNs less than 500,000, 108,326 semiprimes.
978,983 MPNs less than 5,000,000, 979,274 semiprimes.</pre>
 
=={{header|Ring}}==
Line 466 ⟶ 1,146:
497 = 7 x 71
done...
</pre>
 
=={{header|RPL}}==
{{works with|HP|49}}
≪ { 1 }
2 ROT '''FOR''' j
'''IF''' j SQ j DIVIS ΠLIST == '''THEN''' j + '''END'''
'''NEXT'''
≫ '<span style="color:blue">TASK</span>' STO
≪ (1,0)
2 ROT '''FOR''' j
j DIVIS
'''IF CASE'''
DUP SIZE DUP 4 > OVER " < '''THEN''' NOT '''END'''
3 == '''THEN''' 1 '''END'''
DUP 2 GET OVER 3 GET GCD 1 == '''END'''
'''THEN''' SWAP (0,1) + SWAP '''END'''
'''IF''' ΠLIST j SQ == '''THEN''' 1 + '''END'''
'''NEXT'''
≫ '<span style="color:blue">STRETCH</span>' STO
 
500 <span style="color:blue">TASK</span>
500 <span style="color:blue">STRETCH</span>
{{out}}
<pre>
2: { 1 6 8 10 14 15 21 22 26 27 33 34 35 38 39 46 51 55 57 58 62 65 69 74 77 82 85 86 87 91 93 94 95 106 111 115 118 119 122 123 125 129 133 134 141 142 143 145 146 155 158 159 161 166 177 178 183 185 187 194 201 202 203 205 206 209 213 214 215 217 218 219 221 226 235 237 247 249 253 254 259 262 265 267 274 278 287 291 295 298 299 301 302 303 305 309 314 319 321 323 326 327 329 334 335 339 341 343 346 355 358 362 365 371 377 381 382 386 391 393 394 395 398 403 407 411 413 415 417 422 427 437 445 446 447 451 453 454 458 466 469 471 473 478 481 482 485 489 493 497 }
1: (150,153)
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">fn divisors( num : u128 ) -> Vec<u128> {
(1..= num).filter( | &d | num % d == 0 ).collect( )
}
 
fn main() {
println!("{:?}" , (1..= 500).filter( | &d | {
let divis : Vec<u128> = divisors( d ) ;
let prod : u128 = divis.iter( ).product( ) ;
prod == d.checked_pow( 2 ).unwrap( )
}).collect::<Vec<u128>>( ) ) ;
}</syntaxhighlight>
{{out}}
<pre>
[1, 6, 8, 10, 14, 15, 21, 22, 26, 27, 33, 34, 35, 38, 39, 46, 51, 55, 57, 58, 62, 65, 69, 74, 77, 82, 85, 86, 87, 91, 93, 94, 95, 106, 111, 115, 118, 119, 122, 123, 125, 129, 133, 134, 141, 142, 143, 145, 146, 155, 158, 159, 161, 166, 177, 178, 183, 185, 187, 194, 201, 202, 203, 205, 206, 209, 213, 214, 215, 217, 218, 219, 221, 226, 235, 237, 247, 249, 253, 254, 259, 262, 265, 267, 274, 278, 287, 291, 295, 298, 299, 301, 302, 303, 305, 309, 314, 319, 321, 323, 326, 327, 329, 334, 335, 339, 341, 343, 346, 355, 358, 362, 365, 371, 377, 381, 382, 386, 391, 393, 394, 395, 398, 403, 407, 411, 413, 415, 417, 422, 427, 437, 445, 446, 447, 451, 453, 454, 458, 466, 469, 471, 473, 478, 481, 482, 485, 489, 493, 497]
</pre>
 
 
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">func multiplicatively_perfect_numbers(N) {
[1] + semiprimes(N).grep{|n| isqrt(n**tau(n)) == n.sqr } + N.icbrt.primes.map { .cube } -> sort
}
 
say ("Terms <= 500: ", multiplicatively_perfect_numbers(500).join(' '), "\n")
 
for n in (500, 5_000, 50_000, 500_000) {
var M = multiplicatively_perfect_numbers(n)
say "There are #{M.len} MPNs and #{semiprime_count(n)} semiprimes <= #{n.commify}."
}</syntaxhighlight>
{{out}}
<pre>
Terms <= 500: 1 6 8 10 14 15 21 22 26 27 33 34 35 38 39 46 51 55 57 58 62 65 69 74 77 82 85 86 87 91 93 94 95 106 111 115 118 119 122 123 125 129 133 134 141 142 143 145 146 155 158 159 161 166 177 178 183 185 187 194 201 202 203 205 206 209 213 214 215 217 218 219 221 226 235 237 247 249 253 254 259 262 265 267 274 278 287 291 295 298 299 301 302 303 305 309 314 319 321 323 326 327 329 334 335 339 341 343 346 355 358 362 365 371 377 381 382 386 391 393 394 395 398 403 407 411 413 415 417 422 427 437 445 446 447 451 453 454 458 466 469 471 473 478 481 482 485 489 493 497
 
There are 150 MPNs and 153 semiprimes <= 500.
There are 1354 MPNs and 1365 semiprimes <= 5,000.
There are 12074 MPNs and 12110 semiprimes <= 50,000.
There are 108223 MPNs and 108326 semiprimes <= 500,000.
</pre>
 
Line 471 ⟶ 1,218:
{{libheader|Wren-math}}
{{libheader|Wren-fmt}}
This includes '1' as an MPN. Not very quick at around 112 seconds but reasonable for Wren.
<syntaxhighlight lang="ecmascript">import "./math" for Int, Nums
<syntaxhighlight lang="wren">import "./math" for Int, Nums
import "./fmt" for Fmt
 
// library method customized for this task
var divisors = Fn.new { |n|
var divisors = []
var i = 1
var k = (n%2 == 0) ? 1 : 2
while (i <= n.sqrt) {
if (i > 1 && n%i == 0) { // exclude 1 and n
divisors.add(i)
if (divisors.count > 2) break // not eligible if has > 2 divisors
var j = (n/i).floor
if (j != i) divisors.add(j)
}
i = i + k
}
return divisors
}
 
var limit = 500
var count = 0
var i = 01
System.print("Multiplicatively perfect numbers under %(limit):")
while (true) {
var pd = Int.properDivisors(i != 1) ? divisors.skipcall(1i) : [1, 1]
if (pd.count >== 12 && Nums.prod(pd)[0] * pd[1] == i) {
count = count + 1
if (i < 500) {
var pds = pd.map { |d| Fmt.dswrite(3,"$3d d)x }.join($3d", xpd[0], "pd[1])
Fmt.write("$3d = $s ", i, pds)
if (count % 45 == 0) System.print()
}
}
if (i == 499) System.print("\n")
if (i >= limit - 1) {
var squares = Int.primeSieveprimeCount((limit - 1).sqrt.floor).count
var cubes = Int.primeSieveprimeCount((limit - 1).cbrt.floor).count
var count2 = count + squares - cubes - 1
Fmt.print("Counts under $,7d9d: MPNs = $,7d Semi-primes = $,7d", limit, count, count2)
if (limit == 5000005000000) return
limit = limit * 10
}
Line 503 ⟶ 1,268:
<pre>
Multiplicatively perfect numbers under 500:
1 = 1 x 1 6 = 2 x 3 8 = 2 x 4 10 = 2 x 5 14 = 2 x 7
15 = 3 x 5 21 = 3 x 7 22 = 2 x 11 26 = 2 x 13 27 = 3 x 9
2733 = 3 x 11 9 34 33 = 2 x 17 35 = 35 x 11 7 34 38 = 2 x 1719 3539 = 53 x 713
3846 = 2 x 1923 3951 = 3 x 1317 4655 = 25 x 2311 5157 = 3 x 1719 58 = 2 x 29
5562 = 2 x 31 65 = 5 x 1113 5769 = 3 x 1923 5874 = 2 x 2937 6277 = 27 x 3111
6582 = 52 x 1341 6985 = 35 x 2317 7486 = 2 x 3743 7787 = 3 x 29 91 = 7 x 1113
8293 = 3 x 31 94 = 2 x 4147 8595 = 5 x 1719 86106 = 2 x 43 53 87111 = 3 x 2937
91115 = 75 x 1323 93118 = 32 x 3159 119 94 = 7 x 17 122 = 2 x 4761 95123 = 53 x 1941
106125 = 25 x 5325 111129 = 3 x 3743 115133 = 57 x 2319 118134 = 2 x 5967 141 = 3 x 47
119142 = 72 x 1771 122143 = 11 2x 13 145 = 5 x 6129 123146 = 32 x 4173 125155 = 5 x 2531
129158 = 2 x 79 159 = 3 x 4353 133161 = 7 x 1923 134166 = 2 x 6783 141177 = 3 x 4759
142178 = 2 x 7189 143183 = 11 3 x 1361 145185 = 5 x 2937 187 = 11 x 17 146194 = 2 x 7397
155201 = 53 x 3167 158202 = 2 x 101 79 159203 = 37 x 5329 161205 = 75 x 2341 206 = 2 x 103
166209 = 211 x 8319 177213 = 3 x 5971 178214 = 2 x 107 89 215 183 = 5 x 43 217 = 37 x 6131
185218 = 52 x 109 37 219 187 = 3 x 73 221 = 1113 x 17 194226 = 2 x 113 97 201235 = 35 x 6747
202237 = 23 x 101 79 203 247 = 713 x 2919 205249 = 53 x 83 253 = 11 x 4123 206254 = 2 x 103127
209259 = 11 7 x 1937 213262 = 32 x 131 71 214265 = 25 x 107 53 215 267 = 53 x 4389 274 = 2 x 137
217278 = 72 x 139 31 218287 = 27 x 109 41 219 291 = 3 x 7397 221295 = 13 5 x 1759 298 = 2 x 149
226299 = 213 x 113 23 235 301 = 57 x 4743 237302 = 32 x 151 79 303 247 = 3 x 101 305 = 13 5 x 1961
249309 = 3 x 103 83 314 253 = 2 x 157 319 = 11 x 2329 254321 = 23 x 127107 259323 = 717 x 3719
262326 = 2 x 131163 265327 = 53 x 109 53 267329 = 37 x 8947 274334 = 2 x 137167 335 = 5 x 67
278339 = 23 x 139113 287341 = 11 x 31 343 = 7 x 4149 291346 = 32 x 97173 295355 = 5 x 5971
298358 = 2 x 149179 299362 = 13 2 x 181 23 365 301 = 5 x 73 371 = 7 x 4353 302377 = 13 2x x 15129
303381 = 3 x 101127 305382 = 52 x 191 61 309386 = 32 x 103193 314391 = 17 2x 23 393 = 3 x 157131
319394 = 11 2 x 197 29 395 321 = 5 x 79 398 = 32 x 107199 323403 = 1713 x 1931 326407 = 211 x 163 37
327411 = 3 x 109137 329413 = 7 x 4759 334415 = 25 x 167 83 335 417 = 53 x 139 422 = 2 x 67211
339427 = 37 x 113 61 341 437 = 1119 x 3123 343445 = 75 x 4989 346446 = 2 x 173223 447 = 3 x 149
355451 = 511 x 7141 358453 = 23 x 179151 362454 = 2 x 181227 365458 = 52 x 229 466 = 2 x 73233
371469 = 7 x 5367 377471 = 13 3 x 157 29 381473 = 311 x 127 43 382 478 = 2 x 191239 481 = 13 x 37
386482 = 2 x 193241 391485 = 17 5 x 2397 393489 = 3 x 131163 394493 = 17 2x 29 497 = 7 x 197 71
395 = 5 x 79 398 = 2 x 199 403 = 13 x 31 407 = 11 x 37
411 = 3 x 137 413 = 7 x 59 415 = 5 x 83 417 = 3 x 139
422 = 2 x 211 427 = 7 x 61 437 = 19 x 23 445 = 5 x 89
446 = 2 x 223 447 = 3 x 149 451 = 11 x 41 453 = 3 x 151
454 = 2 x 227 458 = 2 x 229 466 = 2 x 233 469 = 7 x 67
471 = 3 x 157 473 = 11 x 43 478 = 2 x 239 481 = 13 x 37
482 = 2 x 241 485 = 5 x 97 489 = 3 x 163 493 = 17 x 29
497 = 7 x 71
 
Counts under 500: MPNs = 149150 Semi-primes = 153
Counts under 5,000: MPNs = 1,353354 Semi-primes = 1,365
Counts under 50,000: MPNs = 12,073074 Semi-primes = 12,110
Counts under 500,000: MPNs = 108,222223 Semi-primes = 108,326
Counts under 5,000,000: MPNs = 978,983 Semi-primes = 979,274
</pre>
 
2,022

edits