Perfect totient numbers: Difference between revisions

m
 
(30 intermediate revisions by 16 users not shown)
Line 15:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">F φ(n)
R sum((1..n).filter(k -> gcd(@n, k) == 1).map(k -> 1))
 
Line 32:
R r
 
print(perfect_totient(20))</langsyntaxhighlight>
 
{{out}}
<pre>
[3, 9, 15, 27, 39, 81, 111, 183, 243, 255, 327, 363, 471, 729, 2187, 2199, 3063, 4359, 4375, 5571]
</pre>
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits <br> or android 64 bits with application Termux }}
<syntaxhighlight lang="aarch64 assembly">
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program totientPerfect64.s */
 
/************************************/
/* Constantes */
/************************************/
.include "../includeConstantesARM64.inc"
.equ MAXI, 20
 
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessNumber: .asciz " @ "
szCarriageReturn: .asciz "\n"
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
/*********************************/
/* code section */
/*********************************/
.text
.global main
main:
mov x4,#2 // start number
mov x6,#0 // line counter
mov x7,#0 // result counter
1:
mov x0,x4
mov x5,#0 // totient sum
2:
bl totient // compute totient
add x5,x5,x0 // add totient
cmp x0,#1
beq 3f
b 2b
3:
cmp x5,x4 // compare number and totient sum
bne 4f
mov x0,x4 // display result if equals
ldr x1,qAdrsZoneConv
bl conversion10 // call décimal conversion
ldr x0,qAdrszMessNumber
ldr x1,qAdrsZoneConv // insert conversion in message
bl strInsertAtCharInc
bl affichageMess // display message
add x7,x7,#1
add x6,x6,#1 // increment indice line display
cmp x6,#5 // if = 5 new line
bne 4f
mov x6,#0
ldr x0,qAdrszCarriageReturn
bl affichageMess
4:
add x4,x4,#1 // increment number
cmp x7,#MAXI // maxi ?
blt 1b // and loop
ldr x0,qAdrszCarriageReturn
bl affichageMess
 
100: // standard end of the program
mov x0, #0 // return code
mov x8,EXIT
svc #0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrsZoneConv: .quad sZoneConv
qAdrszMessNumber: .quad szMessNumber
/******************************************************************/
/* compute totient of number */
/******************************************************************/
/* x0 contains number */
totient:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
mov x4,x0 // totient
mov x5,x0 // save number
mov x1,#0 // for first divisor
1: // begin loop
mul x3,x1,x1 // compute square
cmp x3,x5 // compare number
bgt 4f // end
add x1,x1,#2 // next divisor
udiv x2,x5,x1
msub x3,x1,x2,x5 // compute remainder
cmp x3,#0 // remainder null ?
bne 3f
2: // begin loop 2
udiv x2,x5,x1
msub x3,x1,x2,x5 // compute remainder
cmp x3,#0
csel x5,x2,x5,eq // new value = quotient
beq 2b
udiv x2,x4,x1 // divide totient
sub x4,x4,x2 // compute new totient
3:
cmp x1,#2 // first divisor ?
mov x0,1
csel x1,x0,x1,eq // divisor = 1
b 1b // and loop
4:
cmp x5,#1 // final value > 1
ble 5f
mov x0,x4 // totient
mov x1,x5 // divide by value
udiv x2,x4,x5 // totient divide by value
sub x4,x4,x2 // compute new totient
5:
mov x0,x4
100:
ldp x4,x5,[sp],16 // restaur registers
ldp x2,x3,[sp],16 // restaur registers
ldp x1,lr,[sp],16 // restaur registers
ret
 
 
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../includeARM64.inc"
</syntaxhighlight>
<pre>
3 9 15 27 39
81 111 183 243 255
327 363 471 729 2187
2199 3063 4359 4375 5571
</pre>
=={{header|ALGOL 68}}==
<syntaxhighlight lang="algol68">BEGIN # find the first 20 perfect totient numbers #
# returns the number of integers k where 1 <= k <= n that are mutually prime to n #
PROC totient = ( INT n )INT: # algorithm from the second Go sample #
IF n < 3 THEN 1
ELIF n = 3 THEN 2
ELSE
INT result := n;
INT v := n;
INT i := 2;
WHILE i * i <= v DO
IF v MOD i = 0 THEN
WHILE v MOD i = 0 DO v OVERAB i OD;
result -:= result OVER i
FI;
IF i = 2 THEN
i := 1
FI;
i +:= 2
OD;
IF v > 1 THEN result -:= result OVER v FI;
result
FI # totient # ;
# find the first 20 perfect totient numbers #
INT p count := 0;
FOR i FROM 2 WHILE p count < 20 DO
INT t := totient( i );
INT sum := t;
WHILE t /= 1 DO
t := totient( t );
sum +:= t
OD;
IF sum = i THEN
# have a perfect totient #
p count +:= 1;
print( ( " ", whole( i, 0 ) ) )
FI
OD;
print( ( newline ) )
END</syntaxhighlight>
{{out}}
<pre>
3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571
</pre>
 
=={{header|APL}}==
<langsyntaxhighlight APLlang="apl">(⊢(/⍨)((+/((1+.=⍳∨⊢)∘⊃,⊢)⍣(1=(⊃⊣)))=2∘×)¨)1↓⍳6000</langsyntaxhighlight>
{{out}}
<pre>3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571</pre>
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi <br> or android 32 bits with application Termux}}
<syntaxhighlight lang="arm assembly">
/* ARM assembly Raspberry PI or android with termux */
/* program totientPerfect.s */
 
/* REMARK 1 : this program use routines in a include file
see task Include a file language arm assembly
for the routine affichageMess conversion10
see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes */
/************************************/
.include "../constantes.inc"
.equ MAXI, 20
 
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessNumber: .asciz " @ "
szCarriageReturn: .asciz "\n"
 
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
/*********************************/
/* code section */
/*********************************/
.text
.global main
main:
mov r4,#2 @ start number
mov r6,#0 @ line counter
mov r7,#0 @ result counter
1:
mov r0,r4
mov r5,#0 @ totient sum
2:
bl totient @ compute totient
add r5,r5,r0 @ add totient
cmp r0,#1
beq 3f
b 2b
3:
cmp r5,r4 @ compare number and totient sum
bne 4f
mov r0,r4 @ display result if equals
ldr r1,iAdrsZoneConv
bl conversion10 @ call décimal conversion
ldr r0,iAdrszMessNumber
ldr r1,iAdrsZoneConv @ insert conversion in message
bl strInsertAtCharInc
bl affichageMess @ display message
add r7,r7,#1
add r6,r6,#1 @ increment indice line display
cmp r6,#5 @ if = 5 new line
bne 4f
mov r6,#0
ldr r0,iAdrszCarriageReturn
bl affichageMess
4:
add r4,r4,#1 @ increment number
cmp r7,#MAXI @ maxi ?
blt 1b @ and loop
ldr r0,iAdrszCarriageReturn
bl affichageMess
 
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc #0 @ perform the system call
iAdrszCarriageReturn: .int szCarriageReturn
iAdrsZoneConv: .int sZoneConv
iAdrszMessNumber: .int szMessNumber
/******************************************************************/
/* compute totient of number */
/******************************************************************/
/* r0 contains number */
totient:
push {r1-r5,lr} @ save registers
mov r4,r0 @ totient
mov r5,r0 @ save number
mov r1,#0 @ for first divisor
1: @ begin loop
mul r3,r1,r1 @ compute square
cmp r3,r5 @ compare number
bgt 4f @ end
add r1,r1,#2 @ next divisor
mov r0,r5
bl division
cmp r3,#0 @ remainder null ?
bne 3f
2: @ begin loop 2
mov r0,r5
bl division
cmp r3,#0
moveq r5,r2 @ new value = quotient
beq 2b
mov r0,r4 @ totient
bl division
sub r4,r4,r2 @ compute new totient
3:
cmp r1,#2 @ first divisor ?
moveq r1,#1 @ divisor = 1
b 1b @ and loop
4:
cmp r5,#1 @ final value > 1
ble 5f
mov r0,r4 @ totient
mov r1,r5 @ divide by value
bl division
sub r4,r4,r2 @ compute new totient
5:
mov r0,r4
100:
pop {r1-r5,pc} @ restaur registers
 
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"
</syntaxhighlight>
<pre>
3 9 15 27 39
81 111 183 243 255
327 363 471 729 2187
2199 3063 4359 4375 5571
</pre>
=={{header|Arturo}}==
{{trans|Nim}}
<syntaxhighlight lang="rebol">totient: function [n][
tt: new n
nn: new n
i: new 2
 
while [nn >= i ^ 2][
if zero? nn % i [
while [zero? nn % i]->
'nn / i
'tt - tt/i
]
if i = 2 ->
i: new 1
 
'i + 2
]
if nn > 1 ->
'tt - tt/nn
 
return tt
]
 
x: new 1
num: new 0
 
while [num < 20][
tot: new x
s: new 0
 
while [tot <> 1][
tot: totient tot
's + tot
]
if s = x [
prints ~"|x| "
inc 'num
]
'x + 2
]
print ""</syntaxhighlight>
 
{{out}}
 
<pre>3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571</pre>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">MsgBox, 262144, , % result := perfect_totient(20)
 
perfect_totient(n){
count := sum := tot := 0, str:= "", m := 1
while (count < n) {
tot := m, sum := 0
while (tot != 1) {
tot := totient(tot)
sum += tot
}
if (sum = m) {
str .= m ", "
count++
}
m++
}
return Trim(str, ", ")
}
totient(n) {
tot := n, i := 2
while (i*i <= n) {
if !Mod(n, i) {
while !Mod(n, i)
n /= i
tot -= tot / i
}
if (i = 2)
i := 1
i+=2
}
if (n > 1)
tot -= tot / n
return tot
}</syntaxhighlight>
{{out}}
<pre>3, 9, 15, 27, 39, 81, 111, 183, 243, 255, 327, 363, 471, 729, 2187, 2199, 3063, 4359, 4375, 5571</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f PERFECT_TOTIENT_NUMBERS.AWK
BEGIN {
Line 85 ⟶ 483:
return(tot)
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 93 ⟶ 491:
 
=={{header|BASIC}}==
<langsyntaxhighlight BASIClang="basic">10 DEFINT A-Z
20 N=3
30 S=N: T=0
Line 106 ⟶ 504:
120 IF T=N THEN PRINT N,: Z=Z+1
130 N=N+2
140 IF Z<20 GOTO 30</langsyntaxhighlight>
{{out}}
<pre> 3 9 15 27 39
Line 112 ⟶ 510:
327 363 471 729 2187
2199 3063 4359 4375 5571</pre>
 
==={{header|Applesoft BASIC}}===
{{trans|BASIC}}
<syntaxhighlight lang="qbasic">100 HOME
110 PRINT "The first 20 perfect totient numbers:"
120 n = 3
130 s = n : t = 0
140 x = s : s = 0
150 FOR i = 1 TO x-1
160 a = x : b = i
170 IF B > 0 THEN C = A : A = B : B = C - INT(C / B) * B : GOTO 170
180 IF a = 1 THEN s = s+1
190 NEXT i
200 t = t+s
210 IF s > 1 THEN GOTO 140
220 IF t = n THEN PRINT n;" "; : z = z+1
230 n = n+2
240 IF z < 20 THEN GOTO 130
250 END</syntaxhighlight>
 
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="freebasic">found = 0
curr = 3
 
while found < 20
sum = Totient(curr)
toti = sum
while toti <> 1
toti = Totient(toti)
sum += toti
end while
if sum = curr then
print sum
found += 1
end if
curr += 1
end while
end
 
function GCD(n, d)
if n = 0 then return d
if d = 0 then return n
if n > d then return GCD(d, (n mod d))
return GCD(n, (d mod n))
end function
 
function Totient(n)
phi = 0
for m = 1 to n
if GCD(m, n) = 1 then phi += 1
next m
return phi
end function</syntaxhighlight>
 
==={{header|Chipmunk Basic}}===
{{works with|Chipmunk Basic|3.6.4}}
{{works with|GW-BASIC}}
{{works with|MSX BASIC}}
{{works with|QBasic}}
{{trans|BASIC}}
<syntaxhighlight lang="qbasic">100 CLS
110 PRINT "The first 20 perfect totient numbers:"
120 n = 3
130 s = n : t = 0
140 x = s : s = 0
150 FOR i = 1 TO x-1
160 a = x : b = i
170 IF b > 0 THEN c = a : a = b : b = c MOD b : GOTO 170
180 IF a = 1 THEN s = s+1
190 NEXT i
200 t = t+s
210 IF s > 1 THEN GOTO 140
220 IF t = n THEN PRINT n;" "; : z = z+1
230 n = n+2
240 IF z < 20 THEN GOTO 130
250 END</syntaxhighlight>
 
==={{header|FreeBASIC}}===
Uses the code from the [[Totient_function#FreeBASIC|Totient Function]] example as an include.
 
<syntaxhighlight lang="freebasic">#include"totient.bas"
 
dim as uinteger found = 0, curr = 3, sum, toti
 
while found < 20
sum = totient(curr)
toti = sum
do
toti = totient(toti)
sum += toti
loop while toti <> 1
if sum = curr then
print sum
found += 1
end if
curr += 1
wend</syntaxhighlight>
 
==={{header|Gambas}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vbnet">Public Sub Main()
Dim found As Integer = 0, curr As Integer = 3
Dim sum As Integer, toti As Integer
Print "The first 20 perfect totient numbers are:"
While found < 20
sum = totient(curr)
toti = sum
Do
toti = totient(toti)
sum += toti
Loop While toti <> 1
If sum = curr Then
Print sum; ", ";
found += 1
End If
curr += 1
Wend
Print Chr(8); Chr(8); " "
 
End
 
Function GCD(n As Integer, d As Integer) As Integer
If d = 0 Then Return n Else Return GCD(d, n Mod d)
End Function
 
Function Totient(n As Integer) As Integer
Dim m As Integer, phi As Integer = 0
 
For m = 1 To n
If GCD(m, n) = 1 Then phi += 1
Next
Return phi
End Function</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|GW-BASIC}}===
The [[#Chipmunk Basic|Chipmunk Basic]] solution works without any changes.
 
==={{header|MSX Basic}}===
The [[#Chipmunk Basic|Chipmunk Basic]] solution works without any changes.
 
==={{header|QBasic}}===
The [[#BASIC|BASIC]] solution works without any changes.
Also
The [[#Chipmunk Basic|Chipmunk Basic]] solution works without any changes.
 
=={{header|bc}}==
<syntaxhighlight lang="bc">define gcd (i, j) {
while(j != 0) {
k = j
j = i % j
i = k
}
return i
}
 
define is_perfect_totient (num) {
tot = 0
for (i = 1; i < num; i++) {
if (gcd(num, i) == 1) {
tot += 1
}
}
sum = tot + cache[tot]
cache[num] = sum
return num == sum
}
 
j = 1
count = 0
# we only go to 15 (not 20) because bc is very slow
while (count <= 15) {
if (is_perfect_totient(j)) {
print j, " "
count += 1
}
j += 1
}
print "\n"
quit
</syntaxhighlight>
{{out}}
<pre>
$ time bc -q perfect-totient.bc
3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199
 
real 0m35,553s
user 0m35,437s
sys 0m0,030s
</pre>
 
 
=={{header|BCPL}}==
<langsyntaxhighlight lang="bcpl">get "libhdr"
 
let gcd(a,b) = b=0 -> a, gcd(b, a rem b)
Line 143 ⟶ 740:
$)
wrch('*N')
$)</langsyntaxhighlight>
{{out}}
<pre>3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571</pre>
Line 149 ⟶ 746:
=={{header|C}}==
Calculates as many perfect Totient numbers as entered on the command line.
<langsyntaxhighlight Clang="c">#include<stdlib.h>
#include<stdio.h>
 
Line 209 ⟶ 806:
return 0;
}
</syntaxhighlight>
</lang>
Output for multiple runs, a is the default executable file name produced by GCC
<pre>
Line 227 ⟶ 824:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <cassert>
#include <iostream>
#include <vector>
Line 278 ⟶ 875:
std::cout << '\n';
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 285 ⟶ 882:
3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571
</pre>
=={{header|CLU}}==
<syntaxhighlight lang="clu">gcd = proc (a, b: int) returns (int)
while b ~= 0 do
a, b := b, a//b
end
return(a)
end gcd
 
totient = proc (n: int) returns (int)
tot: int := 0
for i: int in int$from_to(1,n-1) do
if gcd(n,i)=1 then tot := tot + 1 end
end
return(tot)
end totient
 
perfect = proc (n: int) returns (bool)
sum: int := 0
x: int := n
while true do
x := totient(x)
sum := sum + x
if x=1 then break end
end
return(sum = n)
end perfect
 
start_up = proc ()
po: stream := stream$primary_output()
seen: int := 0
n: int := 3
while seen < 20 do
if perfect(n) then
stream$puts(po, int$unparse(n) || " ")
seen := seen + 1
end
n := n + 2
end
end start_up</syntaxhighlight>
{{out}}
<pre>3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571</pre>
=={{header|Cowgol}}==
<langsyntaxhighlight lang="cowgol">include "cowgol.coh";
 
sub gcd(a: uint16, b: uint16): (r: uint16) is
Line 327 ⟶ 965:
n := n + 2;
end loop;
print_nl();</langsyntaxhighlight>
{{out}}
<pre>3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571</pre>
 
=={{header|D}}==
<syntaxhighlight lang="d">import std.stdio;
import std.numeric;
 
int[10000] cache;
 
bool is_perfect_totient(int num) {
int tot = 0;
for (int i = 1; i < num; i++) {
if (gcd(num, i) == 1) {
tot++;
}
}
int sum = tot + cache[tot];
cache[num] = sum;
return num == sum;
}
 
void main() {
int j = 1;
int count = 0;
while (count < 20) {
if (is_perfect_totient(j)) {
printf("%d ", j);
count++;
}
j++;
}
writeln(" ");
}
</syntaxhighlight>
{{out}}
<pre>
3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571
</pre>
 
 
=={{header|Dart}}==
<syntaxhighlight lang="dart">import "dart:io";
 
var cache = List<int>.filled(10000, 0, growable: true);
 
void main() {
cache[0] = 0;
var count = 0;
var i = 1;
while (count < 20) {
if (is_perfect_totient(i)) {
stdout.write("$i ");
count++;
}
i++;
}
print(" ");
}
 
bool is_perfect_totient(n) {
var tot = 0;
for (int i = 1; i < n; i++ ) {
if (i.gcd(n) == 1) {
tot++;
}
}
int sum = tot + cache[tot];
cache[n] = sum;
return n == sum;
}
</syntaxhighlight>
{{out}}
<pre>
3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571
</pre>
 
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
<lang Delphi>
program Perfect_totient_numbers;
 
Line 388 ⟶ 1,099:
writeln(']');
readln;
end.</langsyntaxhighlight>
{{out}}
<pre>
3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571
</pre>
 
=={{header|Draco}}==
<syntaxhighlight lang="draco">proc nonrec gcd(word a, b) word:
word c;
while b ~= 0 do
c := a;
a := b;
b := c % b
od;
a
corp
 
proc nonrec totient(word n) word:
word r, i;
r := 0;
for i from 1 upto n-1 do
if gcd(n,i) = 1 then r := r+1 fi
od;
r
corp
 
proc nonrec perfect(word n) bool:
word sum, x;
sum := 0;
x := n;
while
x := totient(x);
sum := sum + x;
x ~= 1
do od;
sum = n
corp
 
proc nonrec main() void:
word seen, n;
seen := 0;
n := 3;
while seen < 20 do
if perfect(n) then
write(n, " ");
seen := seen + 1
fi;
n := n + 2
od
corp</syntaxhighlight>
{{out}}
<pre>3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571</pre>
 
=={{header|EasyLang}}==
<syntaxhighlight>
func totient n .
tot = n
i = 2
while i <= sqrt n
if n mod i = 0
while n mod i = 0
n = n div i
.
tot -= tot div i
.
if i = 2
i = 1
.
i += 2
.
if n > 1
tot -= tot div n
.
return tot
.
n = 1
while cnt < 20
tot = n
sum = 0
while tot <> 1
tot = totient tot
sum += tot
.
if sum = n
write n & " "
cnt += 1
.
n += 2
.
</syntaxhighlight>
 
{{out}}
<pre>
3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571
</pre>
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: formatting kernel lists lists.lazy math
math.primes.factors ;
 
Line 399 ⟶ 1,204:
 
20 1 lfrom [ perfect? ] lfilter ltake list>array
"%[%d, %]\n" printf</langsyntaxhighlight>
{{out}}
<pre>
{ 3, 9, 15, 27, 39, 81, 111, 183, 243, 255, 327, 363, 471, 729, 2187, 2199, 3063, 4359, 4375, 5571 }
</pre>
 
=={{header|FreeBASIC}}==
Uses the code from the [[Totient_function#FreeBASIC|Totient Function]] example as an include.
 
<lang freebasic>#include"totient.bas"
 
dim as uinteger found = 0, curr = 3, sum, toti
 
while found < 20
sum = totient(curr)
toti = sum
do
toti = totient(toti)
sum += toti
loop while toti <> 1
if sum = curr then
print sum
found += 1
end if
curr += 1
wend</lang>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 486 ⟶ 1,270:
fmt.Println("The first 20 perfect totient numbers are:")
fmt.Println(perfect)
}</langsyntaxhighlight>
 
{{out}}
Line 495 ⟶ 1,279:
 
The following much quicker version uses Euler's product formula rather than repeated invocation of the gcd function to calculate the totient:
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 533 ⟶ 1,317:
fmt.Println("The first 20 perfect totient numbers are:")
fmt.Println(perfect)
}</langsyntaxhighlight>
 
The output is the same as before.
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">perfectTotients :: [Int]
perfectTotients =
filter ((==) <*> (succ . sum . tail . takeWhile (1 /=) . iterate φ)) [2 ..]
Line 549 ⟶ 1,333:
 
main :: IO ()
main = print $ take 20 perfectTotients</langsyntaxhighlight>
{{Out}}
<pre>[3,9,15,27,39,81,111,183,243,255,327,363,471,729,2187,2199,3063,4359,4375,5571]</pre>
 
=={{header|J}}==
<syntaxhighlight lang="j">
<lang J>
Until =: conjunction def 'u^:(0 -: v)^:_'
Filter =: (#~`)(`:6)
Line 560 ⟶ 1,344:
totient_chain =: [: }. (, totient@{:)Until(1={:)
ptnQ =: (= ([: +/ totient_chain))&>
</syntaxhighlight>
</lang>
With these definitions I've found the first 28 perfect totient numbers
<pre>
Line 571 ⟶ 1,355:
 
=={{header|Java}}==
<syntaxhighlight lang="java">
<lang Java>
import java.util.ArrayList;
import java.util.List;
Line 617 ⟶ 1,401:
 
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 625 ⟶ 1,409:
 
=={{header|JavaScript}}==
<langsyntaxhighlight lang="javascript">(() => {
'use strict';
 
Line 759 ⟶ 1,543:
// MAIN ---
main();
})();</langsyntaxhighlight>
{{Out}}
<pre>[3,9,15,27,39,81,111,183,243,255,327,363,471,729,2187,2199,3063,4359,4375,5571]</pre>
Line 766 ⟶ 1,550:
'''Adapted from [[#Julia|Julia]]'''
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
 
One small point of interest in the following implementation is the way the
cacheing of totient values is accomplished using a helper function (`cachephi`).
<syntaxhighlight lang="jq">
<lang jq>
# jq optimizes the recursive call of _gcd in the following:
def gcd(a;b):
Line 803 ⟶ 1,589:
 
"The first 20 perfect totient numbers:",
limit(20; perfect_totients)</langsyntaxhighlight>
{{out}}
<pre>
Line 828 ⟶ 1,614:
5571
</pre>
 
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">using Primes
 
eulerphi(n) = (r = one(n); for (p,k) in factor(abs(n)) r *= p^(k-1)*(p-1) end; r)
Line 859 ⟶ 1,644:
println("The first 20 perfect totient numbers are: $(perfecttotientseries(20))")
println("The first 40 perfect totient numbers are: $(perfecttotientseries(40))")
</langsyntaxhighlight>{{output}}<pre>
The first 20 perfect totient numbers are: [3, 9, 15, 27, 39, 81, 111, 183, 243, 255, 327, 363, 471, 729, 2187, 2199, 3063, 4359, 4375, 5571]
The first 40 perfect totient numbers are: [3, 9, 15, 27, 39, 81, 111, 183, 243, 255, 327, 363, 471, 729, 2187, 2199, 3063, 4359, 4375, 5571, 6561, 8751, 15723, 19683, 36759, 46791, 59049, 65535, 140103, 177147, 208191, 441027, 531441, 1594323, 4190263, 4782969, 9056583, 14348907, 43046721, 57395631]
Line 866 ⟶ 1,651:
=={{header|Kotlin}}==
{{trans|Go}}
<langsyntaxhighlight lang="scala">// Version 1.3.21
 
fun totient(n: Int): Int {
Line 899 ⟶ 1,684:
println("The first 20 perfect totient numbers are:")
println(perfect)
}</langsyntaxhighlight>
 
{{output}}
Line 905 ⟶ 1,690:
The first 20 perfect totient numbers are:
[3, 9, 15, 27, 39, 81, 111, 183, 243, 255, 327, 363, 471, 729, 2187, 2199, 3063, 4359, 4375, 5571]
</pre>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">local function phi(n)
assert(type(n) == 'number', 'n must be a number!')
local result, i = n, 2
while i <= n do
if n % i == 0 then
while n % i == 0 do n = n // i end
result = result - (result // i)
end
if i == 2 then i = 1 end
i = i + 2
end
if n > 1 then result = result - (result // n) end
return result
end
 
local function phi_iter(n)
assert(type(n) == 'number', 'n must be a number!')
if n == 2 then
return phi(n) + 0
else
return phi(n) + phi_iter(phi(n))
end
end
 
local i, count = 2, 0
while count ~= 20 do
if i == phi_iter(i) then
io.write(i, ' ')
count = count + 1
end
i = i + 1
end
</syntaxhighlight>
 
{{output}}
<pre>
3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571
</pre>
 
=={{header|MAD}}==
<langsyntaxhighlight MADlang="mad"> NORMAL MODE IS INTEGER
INTERNAL FUNCTION(Y,Z)
Line 947 ⟶ 1,772:
 
VECTOR VALUES FMT = $I9*$
END OF PROGRAM </langsyntaxhighlight>
{{out}}
<pre> 3
Line 971 ⟶ 1,796:
 
=={{header|Maple}}==
<langsyntaxhighlight Maplelang="maple">iterated_totient := proc(n::posint, total)
if NumberTheory:-Totient(n) = 1 then
return total + 1;
Line 989 ⟶ 1,814:
end if;
end do;
num_list;</langsyntaxhighlight>
{{output}}
<pre>
Line 996 ⟶ 1,821:
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">ClearAll[PerfectTotientNumberQ]
PerfectTotientNumberQ[n_Integer] := Total[Rest[Most[FixedPointList[EulerPhi, n]]]] == n
res = {};
Line 1,004 ⟶ 1,829:
If[PerfectTotientNumberQ[i], AppendTo[res, i]]
]
res</langsyntaxhighlight>
{{out}}
<pre>{3,9,15,27,39,81,111,183,243,255,327,363,471,729,2187,2199,3063,4359,4375,5571}</pre>
 
=={{header|Maxima}}==
<syntaxhighlight lang="maxima">
totientseq(n):=block(
[depth:1,L:n],
while totient(L)#1 do (L:totient(L),depth:depth+1),
j:n,
makelist(j:totient(j),depth),
append([n],%%))$
 
perfect_totient_p(n):=if n=1 then false else is(equal(n,apply("+",rest(totientseq(n)))))$
 
/* Function that returns a list of the first len perfect totient numbers */
perfect_totient_count(len):=block(
[i:1,count:0,result:[]],
while count<len do (if perfect_totient_p(i) then (result:endcons(i,result),count:count+1),i:i+1),
result)$
 
/*Test cases */
perfect_totient_count(20);
</syntaxhighlight>
{{out}}
<pre>
[3,9,15,27,39,81,111,183,243,255,327,363,471,729,2187,2199,3063,4359,4375,5571]
</pre>
 
 
=={{header|Miranda}}==
<syntaxhighlight lang="miranda">main :: [sys_message]
main = [Stdout (show (take 20 perfect) ++ "\n")]
 
perfect :: [num]
perfect = [k | k<-[1..]; k = totientsum k]
 
totientsum :: num->num
totientsum = sum . takewhile (>0) . tl . iterate totient
 
totient :: num->num
totient n = #[k | k<-[1..n-1]; n $gcd k = 1]
 
gcd :: num->num->num
gcd a 0 = a
gcd a b = gcd b (a mod b)</syntaxhighlight>
{{out}}
<pre>[3,9,15,27,39,81,111,183,243,255,327,363,471,729,2187,2199,3063,4359,4375,5571]</pre>
 
=={{header|Modula-2}}==
<syntaxhighlight lang="modula2">MODULE PerfectTotient;
FROM InOut IMPORT WriteCard, WriteLn;
 
CONST Amount = 20;
VAR n, seen: CARDINAL;
 
PROCEDURE GCD(a, b: CARDINAL): CARDINAL;
VAR c: CARDINAL;
BEGIN
WHILE b # 0 DO
c := a MOD b;
a := b;
b := c;
END;
RETURN a;
END GCD;
 
PROCEDURE Totient(n: CARDINAL): CARDINAL;
VAR i, tot: CARDINAL;
BEGIN
tot := 0;
FOR i := 1 TO n/2 DO
IF GCD(n,i) = 1 THEN
tot := tot + 1;
END;
END;
RETURN tot;
END Totient;
 
PROCEDURE Perfect(n: CARDINAL): BOOLEAN;
VAR sum, x: CARDINAL;
BEGIN
sum := 0;
x := n;
REPEAT
x := Totient(x);
sum := sum + x;
UNTIL x = 1;
RETURN sum = n;
END Perfect;
 
BEGIN
seen := 0;
n := 3;
WHILE seen < Amount DO
IF Perfect(n) THEN
WriteCard(n,5);
seen := seen + 1;
IF seen MOD 14 = 0 THEN
WriteLn();
END;
END;
n := n + 2;
END;
WriteLn();
END PerfectTotient.</syntaxhighlight>
{{out}}
<pre> 3 9 15 27 39 81 111 183 243 255 327 363 471 729
2187 2199 3063 4359 4375 5571</pre>
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import strformat
 
func totient(n: int): int =
Line 1,040 ⟶ 1,971:
inc num
inc n, 2
write(stdout, "\n")</langsyntaxhighlight>
{{out}}
<pre>
Line 1,055 ⟶ 1,986:
The c-program takes "real 3m12,481s"<BR>
A test with using floating point/SSE is by 2 seconds faster for 46.th perfect totient number, with the coming new Version of Freepascal 3.2.0
<langsyntaxhighlight lang="pascal">program Perftotient;
{$IFdef FPC}
{$MODE DELPHI} {$CodeAlign proc=32,loop=1}
Line 1,211 ⟶ 2,142:
write(Sollist[j],',');
end;
end.</langsyntaxhighlight>
;OutPut:
<pre>compiled with fpc 3.0.4 -O3 "Perftotient.pas"
Line 1,235 ⟶ 2,166:
=={{header|Perl}}==
{{libheader|ntheory}}
<langsyntaxhighlight lang="perl">use ntheory qw(euler_phi);
 
sub phi_iter {
Line 1,247 ⟶ 2,178:
}
 
printf "The first twenty perfect totient numbers:\n%s\n", join ' ', @perfect;</langsyntaxhighlight>
{{out}}
<pre>The first twenty Perfect totient numbers:
Line 1,254 ⟶ 2,185:
=={{header|Phix}}==
{{trans|Go}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function totient(integer n)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
integer tot = n, i = 2
<span style="color: #008080;">function</span> <span style="color: #000000;">totient</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
while i*i<=n do
<span style="color: #004080;">integer</span> <span style="color: #000000;">tot</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2</span>
if mod(n,i)=0 then
<span style="color: #008080;">while</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">*</span><span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
while true do
<span style="color: #008080;">if</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
n /= i
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
if mod(n,i)!=0 then exit end if
<span style="color: #000000;">n</span> <span style="color: #0000FF;">/=</span> <span style="color: #000000;">i</span>
end while
<span style="color: #008080;">if</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
tot -= tot/i
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
end if
<span style="color: #000000;">tot</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">tot</span><span style="color: #0000FF;">/</span><span style="color: #000000;">i</span>
i += iff(i=2?1:2)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end while
<span style="color: #000000;">i</span> <span style="color: #0000FF;">+=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span><span style="color: #0000FF;">?</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
if n>1 then
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
tot -= tot/n
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">tot</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">tot</span><span style="color: #0000FF;">/</span><span style="color: #000000;">n</span>
return tot
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">tot</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
sequence perfect = {}
integer n = 1
<span style="color: #004080;">sequence</span> <span style="color: #000000;">perfect</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
while length(perfect)<20 do
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
integer tot = n,
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">perfect</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">20</span> <span style="color: #008080;">do</span>
tsum = 0
<span style="color: #004080;">integer</span> <span style="color: #000000;">tot</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span>
while tot!=1 do
<span style="color: #000000;">tsum</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
tot = totient(tot)
<span style="color: #008080;">while</span> <span style="color: #000000;">tot</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
tsum += tot
<span style="color: #000000;">tot</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">totient</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tot</span><span style="color: #0000FF;">)</span>
end while
<span style="color: #000000;">tsum</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">tot</span>
if tsum=n then
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
perfect &= n
<span style="color: #008080;">if</span> <span style="color: #000000;">tsum</span><span style="color: #0000FF;">=</span><span style="color: #000000;">n</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">perfect</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">n</span>
n += 2
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end while
<span style="color: #000000;">n</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">2</span>
printf(1,"The first 20 perfect totient numbers are:\n")
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
?perfect</lang>
<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;">"The first 20 perfect totient numbers are:\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">perfect</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,295 ⟶ 2,229:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(gc 16)
(de gcd (A B)
(until (=0 B)
Line 1,318 ⟶ 2,252:
(inc 'N 2) ) )
(prinl) ) )
(totients)</langsyntaxhighlight>
{{out}}
<pre>
3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571
</pre>
 
=={{header|PILOT}}==
<syntaxhighlight lang="pilot">C :z=0
:n=3
*num
C :s=0
:x=n
*perfect
C :t=0
:i=1
*totient
C :a=x
:b=i
*gcd
C :c=a-b*(a/b)
:a=b
:b=c
J (b>0):*gcd
C (a=1):t=t+1
C :i=i+1
J (i<=x-1):*totient
C :x=t
:s=s+x
J (x<>1):*perfect
T (s=n):#n
C (s=n):z=z+1
C :n=n+2
J (z<20):*num
E :</syntaxhighlight>
{{out}}
<pre>3
9
15
27
39
81
111
183
243
255
327
363
471
729
2187
2199
3063
4359
4375
5571</pre>
 
=={{header|PL/I}}==
<syntaxhighlight lang="pli">perfectTotient: procedure options(main);
gcd: procedure(aa, bb) returns(fixed);
declare (aa, bb, a, b, c) fixed;
a = aa;
b = bb;
do while(b ^= 0);
c = a;
a = b;
b = mod(c, b);
end;
return(a);
end gcd;
totient: procedure(n) returns(fixed);
declare (i, n, s) fixed;
s = 0;
do i=1 to n-1;
if gcd(n,i) = 1 then s = s+1;
end;
return(s);
end totient;
perfect: procedure(n) returns(bit);
declare (n, x, sum) fixed;
sum = 0;
x = n;
do while(x > 1);
x = totient(x);
sum = sum + x;
end;
return(sum = n);
end perfect;
declare (n, seen) fixed;
seen = 0;
do n=3 repeat(n+2) while(seen<20);
if perfect(n) then do;
put edit(n) (F(5));
seen = seen+1;
if mod(seen,10) = 0 then put skip;
end;
end;
end perfectTotient;</syntaxhighlight>
{{out}}
<pre> 3 9 15 27 39 81 111 183 243 255
327 363 471 729 2187 2199 3063 4359 4375 5571</pre>
 
=={{header|PL/M}}==
<langsyntaxhighlight lang="plm">100H:
BDOS: PROCEDURE (FN, ARG); DECLARE FN BYTE, ARG ADDRESS; GO TO 5; END BDOS;
EXIT: PROCEDURE; CALL BDOS(0,0); END EXIT;
Line 1,383 ⟶ 2,415:
END;
CALL EXIT;
EOF</langsyntaxhighlight>
{{out}}
<pre>3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571</pre>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">from math import gcd
from functools import lru_cache
from itertools import islice, count
Line 1,407 ⟶ 2,439:
 
if __name__ == '__main__':
print(list(islice(perfect_totient(), 20)))</langsyntaxhighlight>
 
{{out}}
Line 1,415 ⟶ 2,447:
Alternatively, by composition of generic functions:
 
<langsyntaxhighlight lang="python">'''Perfect totient numbers'''
 
from functools import lru_cache
Line 1,514 ⟶ 2,546:
# MAIN ---
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>[3, 9, 15, 27, 39, 81, 111, 183, 243, 255, 327, 363, 471, 729, 2187, 2199, 3063, 4359, 4375, 5571]</pre>
Line 1,522 ⟶ 2,554:
<code>totient</code> is defined at [[Totient function#Quackery]].
 
<langsyntaxhighlight Quackerylang="quackery"> [ 0 over
[ dup 1 != while
totient
Line 1,535 ⟶ 2,567:
over size 20 =
until ] drop ] is task ( --> )
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,542 ⟶ 2,574:
 
=={{header|Racket}}==
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
(require math/number-theory)
Line 1,563 ⟶ 2,595:
 
(reverse ns)
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 1,569 ⟶ 2,601:
{{works with|Rakudo|2018.11}}
 
<syntaxhighlight lang="raku" perl6line>use Prime::Factor;
 
my \𝜑 = lazy 0, |(1..*).hyper.map: -> \t { t * [*] t.&prime-factors.squish.map: 1 - 1/* }
my \𝜑𝜑 = Nil, |(3, *+2 … *).grep: -> \p { p == sum 𝜑[p], { 𝜑[$_] } … 1 };
 
put "The first twenty Perfect totient numbers:\n", 𝜑𝜑[1..20];</langsyntaxhighlight>
{{out}}
<pre>The first twenty Perfect totient numbers:
Line 1,581 ⟶ 2,613:
=={{header|REXX}}==
===unoptimized===
<langsyntaxhighlight lang="rexx">/*REXX program calculates and displays the first N perfect totient numbers. */
parse arg N . /*obtain optional argument from the CL.*/
if N=='' | N=="," then N= 20 /*Not specified? Then use the default.*/
Line 1,604 ⟶ 2,636:
phi: procedure expose @.; parse arg z; if @.z\==. then return @.z /*was found before?*/
#= z==1; do m=1 for z-1; if gcd(m, z)==1 then #= # + 1; end /*m*/
@.z= #; return # /*use memoization. */</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default input of : &nbsp; &nbsp; <tt> 20 </tt>}}
<pre>
Line 1,617 ⟶ 2,649:
 
('''3<sup>22</sup>''' &nbsp; '''=''' &nbsp; '''31,381,059,609''').
<langsyntaxhighlight lang="rexx">/*REXX program calculates and displays the first N perfect totient numbers. */
parse arg N . /*obtain optional argument from the CL.*/
if N=='' | N=="," then N= 20 /*Not specified? Then use the default.*/
Line 1,642 ⟶ 2,674:
phi: procedure expose @.; parse arg z; if @.z\==. then return @.z /*was found before?*/
#= z==1; do m=1 for z-1; if gcd(m, z)==1 then #= # + 1; end /*m*/
@.z= #; return # /*use memoization. */</langsyntaxhighlight>
{{out|output|text=&nbsp; is identical to the 1<sup>st</sup> REXX version.}} <br><br>
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
perfect = []
n = 1
Line 1,697 ⟶ 2,729:
txt = txt + "]"
see txt
</syntaxhighlight>
</lang>
<pre>
The first 20 perfect totient numbers are:
[3,9,15,27,39,81,111,183,243,255,327,363,471,729,2187,2199,3063,4359,4375,5571]
</pre>
 
=={{header|RPL}}==
{{works with|HP|49}}
« 0 OVER
'''WHILE''' DUP 1 ≠ '''REPEAT'''
EULER SWAP OVER + SWAP
'''END''' DROP ==
» '<span style="color:blue">PTOT?</span>' STO
« → n
« { } 1
'''WHILE''' n '''REPEAT'''
'''IF''' DUP <span style="color:blue">PTOT?</span> '''THEN'''
SWAP OVER + SWAP
'n' 1 STO-
'''END'''
2 + <span style="color:grey">@ Perfect totient numbers are odd</span>
'''END''' DROP
» » '<span style="color:blue">TASK</span>' STO
 
20 <span style="color:blue">TASK</span>
{{out}}
<pre>
1: { 3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571 }
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">require "prime"
 
class Integer
Line 1,724 ⟶ 2,781:
 
puts (1..).lazy.select(&:perfect_totient?).first(20).join(", ")
</syntaxhighlight>
</lang>
{{Out}}
<pre>3, 9, 15, 27, 39, 81, 111, 183, 243, 255, 327, 363, 471, 729, 2187, 2199, 3063, 4359, 4375, 5571
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">use num::integer::gcd;
 
static mut CACHE:[i32;10000] = [0; 10000];
 
fn is_perfect_totient(n: i32) -> bool {
let mut tot = 0;
for i in 1..n {
if gcd(n, i) == 1 {
tot += 1
}
}
unsafe {
let sum = tot + CACHE[tot as usize];
CACHE[n as usize] = sum;
return n == sum;
}
}
 
fn main() {
let mut i = 1;
let mut count = 0;
while count < 20 {
if is_perfect_totient(i) {
print!("{} ", i);
count += 1;
}
i += 1;
}
println!("{}", " ")
}
</syntaxhighlight>
{{Out}}
<pre>3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571
</pre>
 
Line 1,732 ⟶ 2,825:
 
In this example we define a function which determines whether or not a number is a perfect totient number, then use it to construct a lazily evaluated list which contains all perfect totient numbers. Calculating the first n perfect totient numbers only requires taking the first n elements from the list.
<langsyntaxhighlight lang="scala">//List of perfect totients
def isPerfectTotient(num: Int): Boolean = LazyList.iterate(totient(num))(totient).takeWhile(_ != 1).foldLeft(0L)(_+_) + 1 == num
def perfectTotients: LazyList[Int] = LazyList.from(3).filter(isPerfectTotient)
Line 1,738 ⟶ 2,831:
//Totient Function
@tailrec def scrub(f: Long, num: Long): Long = if(num%f == 0) scrub(f, num/f) else num
def totient(num: Long): Long = LazyList.iterate((num, 2: Long, num)){case (ac, i, n) => if(n%i == 0) (ac*(i - 1)/i, i + 1, scrub(i, n)) else (ac, i + 1, n)}.dropWhile(_._3 != 1).head._1</langsyntaxhighlight>
 
{{out}}
Line 1,745 ⟶ 2,838:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func perfect_totient({.<=1}, sum=0) { sum }
func perfect_totient( n, sum=0) { __FUNC__(var(t = n.euler_phi), sum + t) }
 
say (1..Inf -> lazy.grep {|n| perfect_totient(n) == n }.first(20))</langsyntaxhighlight>
{{out}}
<pre>
Line 1,756 ⟶ 2,849:
=={{header|Swift}}==
 
<langsyntaxhighlight lang="swift">public func totient(n: Int) -> Int {
var n = n
var i = 2
Line 1,811 ⟶ 2,904:
 
print("The first 20 perfect totient numbers are:")
print(Array(PerfectTotients().prefix(20)))</langsyntaxhighlight>
 
{{out}}
Line 1,818 ⟶ 2,911:
[3, 9, 15, 27, 39, 81, 111, 183, 243, 255, 327, 363, 471, 729, 2187, 2199, 3063, 4359, 4375, 5571]</pre>
 
 
=={{header|Wren}}==
=={{transheader|GoTcl}}==
 
The version using Euler's product formula.
<syntaxhighlight lang="tcl">array set cache {}
<lang ecmascript>var totient = Fn.new { |n|
 
var tot = n
set cache(0) 0
var i = 2
 
while (i*i <= n) {
proc gcd {i j} {
if (n%i == 0) {
while {$j != 0} {
while(n%i == 0) n = (n/i).floor
set t [expr {$i % tot = tot - (tot/i).floor$j}]
set i $j
set j $t
}
return $i
}
 
proc is_perfect_totient {n} {
global cache
set tot 0
for {set i 1} {$i < $n} {incr i} {
if [ expr [gcd $i $n] == 1 ] {
incr tot
}
if (i == 2) i = 1
i = i + 2
}
ifset (n > 1) totsum =[expr $tot -+ $cache($tot/n).floor]
set cache($n) $sum
return tot
return [ expr $n == $sum ? 1 : 0]
}
 
set i 1
set count 0
while { $count < 20 } {
if [ is_perfect_totient $i ] {
puts -nonewline "${i} "
incr count
}
incr i
}
puts ""
</syntaxhighlight>
{{out}}
<pre>
$ time tclsh perfect-totient.tcl
3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571
 
real 1m18,058s
user 1m17,593s
sys 0m0,046s
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-math}}
The version using Euler's product formula.
<syntaxhighlight lang="wren">import "./math" for Int
 
var perfect = []
Line 1,842 ⟶ 2,973:
var sum = 0
while (tot != 1) {
tot = totientInt.calltotient(tot)
sum = sum + tot
}
Line 1,849 ⟶ 2,980:
}
System.print("The first 20 perfect totient numbers are:")
System.print(perfect)</langsyntaxhighlight>
 
{{out}}
Line 1,856 ⟶ 2,987:
[3, 9, 15, 27, 39, 81, 111, 183, 243, 255, 327, 363, 471, 729, 2187, 2199, 3063, 4359, 4375, 5571]
</pre>
 
=={{header|XPL0}}==
{{trans|Wren}}
<syntaxhighlight lang "XPL0">func Totient(N);
int N, Tot, I;
[Tot:= N; I:= 2;
while I*I <= N do
[if rem(N/I) = 0 then
[while rem(N/I) = 0 do N:= N/I;
Tot:= Tot - Tot/I;
];
if I = 2 then I:= 1;
I:= I+2;
];
if N > 1 then Tot:= Tot - Tot/N;
return Tot;
];
 
proc ShowPerfect;
int N, Count, Tot, Sum;
[N:= 1; Count:= 0;
while Count < 20 do
[Tot:= N; Sum:= 0;
while Tot # 1 do
[Tot:= Totient(Tot);
Sum:= Sum + Tot;
];
if Sum = N then
[IntOut(0, N); ChOut(0, ^ );
Count:= Count+1;
];
N:= N+2;
];
];
 
[Text(0, "The first 20 perfect totient numbers are:^m^j");
ShowPerfect;
]</syntaxhighlight>
{{out}}
<pre>
The first 20 perfect totient numbers are:
3 9 15 27 39 81 111 183 243 255 327 363 471 729 2187 2199 3063 4359 4375 5571 </pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">var totients=List.createLong(10_000,0); // cache
fcn totient(n){ if(phi:=totients[n]) return(phi);
totients[n]=[1..n].reduce('wrap(p,k){ p + (n.gcd(k)==1) })
Line 1,868 ⟶ 3,041:
if(parts==z) z else Void.Skip;
})
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">perfectTotientW().walk(20).println();</langsyntaxhighlight>
{{out}}
<pre>
1,150

edits