Totient function

From Rosetta Code
Task
Totient function
You are encouraged to solve this task according to the task description, using any language you may know.

The   totient   function is also known as:

  •   Euler's totient function
  •   Euler's phi totient function
  •   phi totient function
  •   Φ   function   (uppercase Greek phi)
  •   φ    function   (lowercase Greek phi)


Definitions   (as per number theory)

The totient function:

  •   counts the integers up to a given positive integer   n   that are relatively prime to   n
  •   counts the integers   k   in the range   1 ≤ k ≤ n   for which the greatest common divisor   gcd(n,k)   is equal to   1
  •   counts numbers   ≤ n   and   prime to   n


If the totient number   (for N)   is one less than   N,   then   N   is prime.


Task

Create a   totient   function and:

  •   Find and display   (1 per line)   for the 1st   25   integers:
  •   the integer   (the index)
  •   the totient number for that integer
  •   indicate if that integer is prime
  •   Find and display the   count   of the primes up to          100
  •   Find and display the   count   of the primes up to       1,000
  •   Find and display the   count   of the primes up to     10,000
  •   Find and display the   count   of the primes up to   100,000     (optional)

Show all output here.


Related task


Also see


11l

Translation of: Python
F f(n)
   R sum((1..n).filter(k -> gcd(@n, k) == 1).map(k -> 1))

F is_prime(n)
   R f(n) == n - 1

L(n) 1..25
   print(‘ f(#.) == #.’.format(n, f(n))‘’(I is_prime(n) {‘, is prime’} E ‘’))
V count = 0
L(n) 1..10'000
   count += is_prime(n)
   I n C (100, 1000, 10'000)
      print(‘Primes up to #.: #.’.format(n, count))
Output:
 f(1) == 1
 f(2) == 1, is prime
 f(3) == 2, is prime
 f(4) == 2
 f(5) == 4, is prime
 f(6) == 2
 f(7) == 6, is prime
 f(8) == 4
 f(9) == 6
 f(10) == 4
 f(11) == 10, is prime
 f(12) == 4
 f(13) == 12, is prime
 f(14) == 6
 f(15) == 8
 f(16) == 8
 f(17) == 16, is prime
 f(18) == 6
 f(19) == 18, is prime
 f(20) == 8
 f(21) == 12
 f(22) == 10
 f(23) == 22, is prime
 f(24) == 8
 f(25) == 20
Primes up to 100: 25
Primes up to 1000: 168
Primes up to 10000: 1229

AArch64 Assembly

Works with: as version Raspberry Pi 3B version Buster 64 bits
or android 64 bits with application Termux
/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program totient.s   */

/************************************/
/* Constantes                       */
/************************************/
.include "../includeConstantesARM64.inc" 
.equ MAXI,      25

/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessNumber:       .asciz " number @ totient @  @ \n"
szCarriageReturn:   .asciz "\n"
szMessPrime:        .asciz " is prime."
szMessSpace:        .asciz " "
szMessCounterPrime: .asciz "Number of primes to @ : @ \n"
szMessOverflow:     .asciz "Overflow function isPrime.\n"
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss  
sZoneConv:           .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main 
main:
    mov x4,#1                   // start number
1: 
    mov x0,x4
    bl totient                  // compute totient
    mov x5,x0
    mov x0,x4
    bl isPrime                  // control if number is prime
    mov x6,x0
    mov x0,x4                   // display result
    ldr x1,qAdrsZoneConv
    bl conversion10             // call décimal conversion
    ldr x0,qAdrszMessNumber
    ldr x1,qAdrsZoneConv        // insert conversion in message
    bl strInsertAtCharInc
    mov x7,x0
    mov x0,x5
    ldr x1,qAdrsZoneConv
    bl conversion10             // call décimal conversion
    mov x0,x7
    ldr x1,qAdrsZoneConv        // insert conversion in message
    bl strInsertAtCharInc
    mov x7,x0
    cmp x6,#1
    ldr x1,qAdrszMessPrime
    ldr x8,qAdrszMessSpace
    csel x1,x1,x8,eq
    mov x0,x7
    bl strInsertAtCharInc
    bl affichageMess             // display message
    
    add x4,x4,#1                 // increment number
    cmp x4,#MAXI                 // maxi ?
    ble 1b                       // and loop
    
    mov x4,#2                    // first number 
    mov x5,#0                    // prime counter 
    ldr x6,iCst1000              // load constantes
    ldr x7,iCst10000
    ldr x8,iCst100000
2:
    mov x0,x4
    bl isPrime
    cmp x0,#0
    beq 3f
    add x5,x5,#1
3:
    add x4,x4,#1
    cmp x4,#100
    bne 4f
    mov x0,#100
    mov x1,x5
    bl displayCounter
    b 7f
4:
    cmp x4,x6        // 1000
    bne 5f
    mov x0,x6
    mov x1,x5
    bl displayCounter
    b 7f
5:
    cmp x4,x7        // 10000
    bne 6f
    mov x0,x7
    mov x1,x5
    bl displayCounter
    b 7f
6:
    cmp x4,x8        // 100000
    bne 7f
    mov x0,x8
    mov x1,x5
    bl displayCounter
7:
    cmp x4,x8
    ble 2b                      // and loop

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
qAdrszMessCounterPrime:  .quad szMessCounterPrime
qAdrszMessPrime:         .quad szMessPrime
qAdrszMessSpace:         .quad szMessSpace
iCst1000:                .quad 1000
iCst10000:               .quad 10000
iCst100000:              .quad 100000
/******************************************************************/
/*    display counter                                             */ 
/******************************************************************/
/* x0 contains limit  */
/* x1 contains counter */
displayCounter:
    stp x1,lr,[sp,-16]!          // save  registers 
    stp x2,x3,[sp,-16]!          // save  registers 
    mov x2,x1
    ldr x1,qAdrsZoneConv
    bl conversion10             // call décimal conversion
    ldr x0,qAdrszMessCounterPrime
    ldr x1,qAdrsZoneConv        // insert conversion in message
    bl strInsertAtCharInc
    mov x3,x0
    mov x0,x2
    ldr x1,qAdrsZoneConv
    bl conversion10             // call décimal conversion
    mov x0,x3
    ldr x1,qAdrsZoneConv        // insert conversion in message
    bl strInsertAtCharInc
    bl affichageMess
100:
    ldp x2,x3,[sp],16        // restaur  registers 
    ldp x1,lr,[sp],16            // restaur  registers
    ret 
/******************************************************************/
/*     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 
/***************************************************/
/*   Verification si un nombre est premier         */
/***************************************************/
/* x0 contient le nombre à verifier */
/* x0 retourne 1 si premier  0 sinon */
isPrime:
    stp x1,lr,[sp,-16]!        // save  registres
    stp x2,x3,[sp,-16]!        // save  registres
    mov x2,x0
    sub x1,x0,#1
    cmp x2,0
    beq 99f                    // retourne zéro
    cmp x2,2                   // pour 1 et 2 retourne 1
    ble 2f
    mov x0,#2
    bl moduloPur64
    bcs 100f                   // erreur overflow
    cmp x0,#1
    bne 99f                    // Pas premier
    cmp x2,3
    beq 2f
    mov x0,#3
    bl moduloPur64
    blt 100f                   // erreur overflow
    cmp x0,#1
    bne 99f

    cmp x2,5
    beq 2f
    mov x0,#5
    bl moduloPur64
    bcs 100f                   // erreur overflow
    cmp x0,#1
    bne 99f                    // Pas premier

    cmp x2,7
    beq 2f
    mov x0,#7
    bl moduloPur64
    bcs 100f                   // erreur overflow
    cmp x0,#1
    bne 99f                    // Pas premier

    cmp x2,11
    beq 2f
    mov x0,#11
    bl moduloPur64
    bcs 100f                   // erreur overflow
    cmp x0,#1
    bne 99f                    // Pas premier

    cmp x2,13
    beq 2f
    mov x0,#13
    bl moduloPur64
    bcs 100f                   // erreur overflow
    cmp x0,#1
    bne 99f                    // Pas premier
    
    cmp x2,17
    beq 2f
    mov x0,#17
    bl moduloPur64
    bcs 100f                   // erreur overflow
    cmp x0,#1
    bne 99f                    // Pas premier
2:
    cmn x0,0                   // carry à zero pas d'erreur
    mov x0,1                   // premier
    b 100f
99:
    cmn x0,0                   // carry à zero pas d'erreur
    mov x0,#0                  // Pas premier
100:
    ldp x2,x3,[sp],16          // restaur des  2 registres
    ldp x1,lr,[sp],16          // restaur des  2 registres
    ret                        // retour adresse lr x30

/**************************************************************/
/********************************************************/
/*   Calcul modulo de b puissance e modulo m  */
/*    Exemple 4 puissance 13 modulo 497 = 445         */
/********************************************************/
/* x0  nombre  */
/* x1 exposant */
/* x2 modulo   */
moduloPur64:
    stp x1,lr,[sp,-16]!        // save  registres
    stp x3,x4,[sp,-16]!        // save  registres
    stp x5,x6,[sp,-16]!        // save  registres
    stp x7,x8,[sp,-16]!        // save  registres
    stp x9,x10,[sp,-16]!        // save  registres
    cbz x0,100f
    cbz x1,100f
    mov x8,x0
    mov x7,x1
    mov x6,1                   // resultat
    udiv x4,x8,x2
    msub x9,x4,x2,x8           // contient le reste
1:
    tst x7,1
    beq 2f
    mul x4,x9,x6
    umulh x5,x9,x6
    //cbnz x5,99f
    mov x6,x4
    mov x0,x6
    mov x1,x5
    bl divisionReg128U
    cbnz x1,99f                // overflow
    mov x6,x3
2:
    mul x8,x9,x9
    umulh x5,x9,x9
    mov x0,x8
    mov x1,x5
    bl divisionReg128U
    cbnz x1,99f                // overflow
    mov x9,x3
    lsr x7,x7,1
    cbnz x7,1b
    mov x0,x6                  // result
    cmn x0,0                   // carry à zero pas d'erreur
    b 100f
99:
    ldr x0,qAdrszMessOverflow
    bl  affichageMess
    cmp x0,0                   // carry à un car erreur
    mov x0,-1                  // code erreur

100:
    ldp x9,x10,[sp],16          // restaur des  2 registres
    ldp x7,x8,[sp],16          // restaur des  2 registres
    ldp x5,x6,[sp],16          // restaur des  2 registres
    ldp x3,x4,[sp],16          // restaur des  2 registres
    ldp x1,lr,[sp],16          // restaur des  2 registres
    ret                        // retour adresse lr x30
qAdrszMessOverflow:         .quad  szMessOverflow
/***************************************************/
/*   division d un nombre de 128 bits par un nombre de 64 bits */
/***************************************************/
/* x0 contient partie basse dividende */
/* x1 contient partie haute dividente */
/* x2 contient le diviseur */
/* x0 retourne partie basse quotient */
/* x1 retourne partie haute quotient */
/* x3 retourne le reste */
divisionReg128U:
    stp x6,lr,[sp,-16]!        // save  registres
    stp x4,x5,[sp,-16]!        // save  registres
    mov x5,#0                  // raz du reste R
    mov x3,#128                // compteur de boucle
    mov x4,#0                  // dernier bit
1:    
    lsl x5,x5,#1               // on decale le reste de 1
    tst x1,1<<63               // test du bit le plus à gauche
    lsl x1,x1,#1               // on decale la partie haute du quotient de 1
    beq 2f
    orr  x5,x5,#1              // et on le pousse dans le reste R
2:
    tst x0,1<<63
    lsl x0,x0,#1               // puis on decale la partie basse 
    beq 3f
    orr x1,x1,#1               // et on pousse le bit de gauche dans la partie haute
3:
    orr x0,x0,x4               // position du dernier bit du quotient
    mov x4,#0                  // raz du bit
    cmp x5,x2
    blt 4f
    sub x5,x5,x2                // on enleve le diviseur du reste
    mov x4,#1                   // dernier bit à 1
4:
                               // et boucle
    subs x3,x3,#1
    bgt 1b    
    lsl x1,x1,#1               // on decale le quotient de 1
    tst x0,1<<63
    lsl x0,x0,#1              // puis on decale la partie basse 
    beq 5f
    orr x1,x1,#1
5:
    orr x0,x0,x4                  // position du dernier bit du quotient
    mov x3,x5
100:
    ldp x4,x5,[sp],16          // restaur des  2 registres
    ldp x6,lr,[sp],16          // restaur des  2 registres
    ret                        // retour adresse lr x30


/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
.include "../includeARM64.inc"
number 1 totient 1   is prime.
 number 2 totient 1   is prime.
 number 3 totient 2   is prime.
 number 4 totient 2
 number 5 totient 4   is prime.
 number 6 totient 2
 number 7 totient 6   is prime.
 number 8 totient 4
 number 9 totient 6
 number 10 totient 4
 number 11 totient 10   is prime.
 number 12 totient 4
 number 13 totient 12   is prime.
 number 14 totient 6
 number 15 totient 8
 number 16 totient 8
 number 17 totient 16   is prime.
 number 18 totient 6
 number 19 totient 18   is prime.
 number 20 totient 8
 number 21 totient 12
 number 22 totient 10
 number 23 totient 22   is prime.
 number 24 totient 8
 number 25 totient 20
Number of primes to 100 : 25
Number of primes to 1000 : 168
Number of primes to 10000 : 1229
Number of primes to 100000 : 9592

Ada

Translation of: C
with Ada.Text_IO;
with Ada.Integer_Text_IO;

procedure Totient is

   function Totient (N : in Integer) return Integer is
      Tot : Integer := N;
      I   : Integer;
      N2  : Integer := N;
   begin
      I := 2;
      while I * I <= N2 loop
         if N2 mod I = 0 then
            while N2 mod I = 0 loop
               N2 := N2 / I;
            end loop;
            Tot := Tot - Tot / I;
         end if;

         if I = 2 then
            I := 1;
         end if;
         I := I + 2;
      end loop;

      if N2 > 1 then
         Tot := Tot - Tot / N2;
      end if;

      return Tot;
   end Totient;

   Count : Integer := 0;
   Tot   : Integer;
   Placeholder : String := "  n  Phi  Is_Prime";
   Image_N     : String renames Placeholder ( 1 ..  3);
   Image_Phi   : String renames Placeholder ( 6 ..  8);
   Image_Prime : String renames Placeholder (11 .. 17);
   use Ada.Text_IO;
   use Ada.Integer_Text_IO;
begin

   Put_Line (Placeholder);

   for N in 1 .. 25 loop
      Tot := Totient (N);

      if N - 1 = Tot then
         Count := Count + 1;
      end if;
      Put (Image_N, N);
      Put (Image_Phi, Tot);
      Image_Prime := (if N - 1 = Tot then "    True" else "   False");
      Put_Line (Placeholder);
   end loop;
   New_Line;

   Put_Line ("Number of primes up to " & Integer'(25)'Image &" =" & Count'Image);

   for N in 26 .. 100_000 loop
      Tot := Totient (N);

      if Tot = N - 1 then
         Count := Count + 1;
      end if;

      if N = 100 or N = 1_000 or N mod 10_000 = 0 then
         Put_Line ("Number of primes up to " & N'Image & " =" & Count'Image);
      end if;
   end loop;

end Totient;
Output:
  n  Phi  Is_Prime
  1    1     False
  2    1      True
  3    2      True
  4    2     False
  5    4      True
  6    2     False
  7    6      True
  8    4     False
  9    6     False
 10    4     False
 11   10      True
 12    4     False
 13   12      True
 14    6     False
 15    8     False
 16    8     False
 17   16      True
 18    6     False
 19   18      True
 20    8     False
 21   12     False
 22   10     False
 23   22      True
 24    8     False
 25   20     False

Number of primes up to  25 = 9
Number of primes up to  100 = 25
Number of primes up to  1000 = 168
Number of primes up to  10000 = 1229
Number of primes up to  20000 = 2262
Number of primes up to  30000 = 3245
Number of primes up to  40000 = 4203
Number of primes up to  50000 = 5133
Number of primes up to  60000 = 6057
Number of primes up to  70000 = 6935
Number of primes up to  80000 = 7837
Number of primes up to  90000 = 8713
Number of primes up to  100000 = 9592

ALGOL 68

Translation of: Go

Uses the totient algorithm from the second Go sample.

BEGIN
    # returns the number of integers k where 1 <= k <= n that are mutually prime to n #
    PROC totient = ( INT n )INT:
        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 # ;
    # show the totient function values for the first 25 integers #
    print( ( " n  phi(n) remarks", newline ) );
    FOR n TO 25 DO
        INT tn = totient( n );
        print( ( whole( n, -2 ), ": ", whole( tn, -5 )
               , IF tn = n - 1 AND tn /= 0 THEN "  n is prime" ELSE "" FI, newline
               )
             )
    OD;
    # use the totient function to count primes #
    INT n100 := 0, n1000 := 0, n10000 := 0, n100000 := 0;
    FOR n TO 100 000 DO
        IF totient( n ) = n - 1 THEN
            IF n <=     100 THEN    n100 +:= 1 FI;
            IF n <=   1 000 THEN   n1000 +:= 1 FI;
            IF n <=  10 000 THEN  n10000 +:= 1 FI;
            IF n <= 100 000 THEN n100000 +:= 1 FI
        FI
    OD;
    print( ( "There are ", whole(    n100, -6 ), " primes below      100", newline ) );
    print( ( "There are ", whole(   n1000, -6 ), " primes below    1 000", newline ) );
    print( ( "There are ", whole(  n10000, -6 ), " primes below   10 000", newline ) );
    print( ( "There are ", whole( n100000, -6 ), " primes below  100 000", newline ) )
END
Output:
 n  phi(n) remarks
 1:     1
 2:     1  n is prime
 3:     2  n is prime
 4:     2
 5:     4  n is prime
 6:     2
 7:     6  n is prime
 8:     4
 9:     6
10:     4
11:    10  n is prime
12:     4
13:    12  n is prime
14:     6
15:     8
16:     8
17:    16  n is prime
18:     6
19:    18  n is prime
20:     8
21:    12
22:    10
23:    22  n is prime
24:     8
25:    20
There are     25 primes below      100
There are    168 primes below    1 000
There are   1229 primes below   10 000
There are   9592 primes below  100 000

ALGOL-M

The GCD approach is straight-forward and easy to follow, but is not particularly efficient.

BEGIN

%  RETURN P MOD Q  %
INTEGER FUNCTION MOD (P, Q);
INTEGER P, Q;
BEGIN
	MOD := P - Q * (P / Q);
END;

%  RETURN GREATEST COMMON DIVISOR OF X AND Y  %
INTEGER FUNCTION GCD (X, Y);
INTEGER X, Y;
BEGIN
	INTEGER R;
	IF X < Y THEN
	BEGIN
		INTEGER TEMP;
		TEMP := X;
		X := Y;
		Y := TEMP;
	END;
	WHILE (R := MOD(X, Y)) <> 0 DO
	BEGIN
		X := Y;
		Y := R;
	END;
	GCD := Y;
END;

% RETURN PHI (ALSO CALLED TOTIENT) OF N %
INTEGER FUNCTION PHI(N);
INTEGER N;
BEGIN
	INTEGER I, COUNT;
    COUNT := 1;
    FOR I := 2 STEP 1 UNTIL N DO
	BEGIN
		IF GCD(N,I) = 1 THEN COUNT := COUNT + 1;
 	END;
	PHI := COUNT;
END;

COMMENT - EXERCISE THE FUNCTION;
INTEGER N, TOTIENT, COUNT;
WRITE("    N   PHI(N)  PRIME?");
FOR N := 1 STEP 1 UNTIL 25 DO
BEGIN
    WRITE(N, (TOTIENT := PHI(N)));
    WRITEON(IF TOTIENT = (N-1) THEN "   YES" ELSE "   NO");
END;

COMMENT - AND USE IT TO COUNT PRIMES;
WRITE("");
COUNT := 0;
FOR N := 1 STEP 1 UNTIL 1000 DO
BEGIN
   	IF PHI(N) = (N-1) THEN COUNT := COUNT + 1;
   	IF N = 100 THEN 
		WRITE("PRIMES UP TO 100 =", COUNT)
    ELSE IF N = 1000 THEN 
		WRITE("PRIMES UP TO 1000 =", COUNT);
END;
       

END
Output:

Limiting the search to 1000 keeps the running time of the program within reasonable bounds.

    N   PHI(N)  PRIME?
     1     1    NO
     2     1    YES
     3     2    YES
     4     2    NO
     5     4    YES
     6     2    NO
     7     6    YES
     8     4    NO
     9     6    NO
    10     4    NO
    11    10    YES
    12     4    NO
    13    12    YES
    14     6    NO
    15     8    NO
    16     8    NO
    17    16    YES
    18     6    NO
    19    18    YES
    20     8    NO
    21    12    NO
    22    10    NO
    23    22    YES
    24     8    NO
    25    20    NO
   
PRIMES UP TO 100 =   25
PRIMES UP TO 1000 =  168

APL

Works with: Dyalog APL
task{
    totient  1+.=⍳∨⊢
    prime    totient=-1

    'Index' 'Totient' 'Prime',(⊢⍪totient¨,[÷2]prime¨)25
    {'There are' (+/prime¨) 'primes below' }¨100 1000 10000
}
Output:
 Index    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 Totient  1 1 2 2 4 2 6 4 6  4 10  4 12  6  8  8 16  6 18  8 12 10 22  8 20
 Prime    0 1 1 0 1 0 1 0 0  0  1  0  1  0  0  0  1  0  1  0  0  0  1  0  0
 There are  25  primes below  100
 There are  168  primes below  1000
 There are  1229  primes below  10000

ARM Assembly

Works with: as version Raspberry Pi
or android 32 bits with application Termux
/* ARM assembly Raspberry PI or android with termux */
/*  program totient.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,      25

/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessNumber:       .asciz " number @ totient @  @ \n"
szCarriageReturn:   .asciz "\n"
szMessPrime:        .asciz " is prime."
szMessSpace:        .asciz " "
szMessCounterPrime: .asciz "Number of primes to @ : @ \n"
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss  
sZoneConv:           .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main 
main:
    mov r4,#1                   @ start number
1: 
    mov r0,r4
    bl totient                  @ compute totient
    mov r5,r0
    mov r0,r4
    bl isPrime                  @ control if number is prime
    mov r6,r0
    mov r0,r4                   @ display result
    ldr r1,iAdrsZoneConv
    bl conversion10             @ call décimal conversion
    ldr r0,iAdrszMessNumber
    ldr r1,iAdrsZoneConv        @ insert conversion in message
    bl strInsertAtCharInc
    mov r7,r0
    mov r0,r5
    ldr r1,iAdrsZoneConv
    bl conversion10             @ call décimal conversion
    mov r0,r7
    ldr r1,iAdrsZoneConv        @ insert conversion in message
    bl strInsertAtCharInc
    mov r7,r0
    cmp r6,#1
    ldreq r1,iAdrszMessPrime
    ldrne r1,iAdrszMessSpace
    mov r0,r7
    bl strInsertAtCharInc
    bl affichageMess             @ display message
    
    add r4,r4,#1                 @ increment number
    cmp r4,#MAXI                 @ maxi ?
    ble 1b                       @ and loop
    
    mov r4,#2                    @ first number 
    mov r5,#0                    @ prime counter 
    ldr r6,iCst1000              @ load constantes
    ldr r7,iCst10000
    ldr r8,iCst100000
2:
    mov r0,r4
    bl isPrime
    cmp r0,#0
    beq 3f
    add r5,r5,#1
3:
    add r4,r4,#1
    cmp r4,#100
    bne 4f
    mov r0,#100
    mov r1,r5
    bl displayCounter
    b 7f
4:
    cmp r4,r6        @ 1000
    bne 5f
    mov r0,r6
    mov r1,r5
    bl displayCounter
    b 7f
5:
    cmp r4,r7        @ 10000
    bne 6f
    mov r0,r7
    mov r1,r5
    bl displayCounter
    b 7f
6:
    cmp r4,r8        @ 100000
    bne 7f
    mov r0,r8
    mov r1,r5
    bl displayCounter
7:
    cmp r4,r8
    ble 2b                      @ and loop

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
iAdrszMessCounterPrime:  .int szMessCounterPrime
iAdrszMessPrime:         .int szMessPrime
iAdrszMessSpace:         .int szMessSpace
iCst1000:                .int 1000
iCst10000:               .int 10000
iCst100000:              .int 100000
/******************************************************************/
/*    display counter                                             */ 
/******************************************************************/
/* r0 contains limit  */
/* r1 contains counter */
displayCounter:
    push {r1-r3,lr}           @ save  registers 
    mov r2,r1
    ldr r1,iAdrsZoneConv
    bl conversion10             @ call décimal conversion
    ldr r0,iAdrszMessCounterPrime
    ldr r1,iAdrsZoneConv        @ insert conversion in message
    bl strInsertAtCharInc
    mov r3,r0
    mov r0,r2
    ldr r1,iAdrsZoneConv
    bl conversion10             @ call décimal conversion
    mov r0,r3
    ldr r1,iAdrsZoneConv        @ insert conversion in message
    bl strInsertAtCharInc
    bl affichageMess
100:
    pop {r1-r3,pc}             @ restaur registers
/******************************************************************/
/*     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

/***************************************************/
/*   check if a number is prime              */
/***************************************************/
/* r0 contains the number            */
/* r0 return 1 if prime  0 else */
@2147483647
@4294967297
@131071
isPrime:
    push {r1-r6,lr}    @ save registers 
    cmp r0,#0
    beq 90f
    cmp r0,#17
    bhi 1f
    cmp r0,#3
    bls 80f            @ for 1,2,3 return prime
    cmp r0,#5
    beq 80f            @ for 5 return prime
    cmp r0,#7
    beq 80f            @ for 7 return prime
    cmp r0,#11
    beq 80f            @ for 11 return prime
    cmp r0,#13
    beq 80f            @ for 13 return prime
    cmp r0,#17
    beq 80f            @ for 17 return prime
1:
    tst r0,#1          @ even ?
    beq 90f            @ yes -> not prime
    mov r2,r0          @ save number
    sub r1,r0,#1       @ exposant n - 1
    mov r0,#3          @ base
    bl moduloPuR32     @ compute base power n - 1 modulo n
    cmp r0,#1
    bne 90f            @ if <> 1  -> not prime
 
    mov r0,#5
    bl moduloPuR32
    cmp r0,#1
    bne 90f
    
    mov r0,#7
    bl moduloPuR32
    cmp r0,#1
    bne 90f
    
    mov r0,#11
    bl moduloPuR32
    cmp r0,#1
    bne 90f
    
    mov r0,#13
    bl moduloPuR32
    cmp r0,#1
    bne 90f
    
    mov r0,#17
    bl moduloPuR32
    cmp r0,#1
    bne 90f
80:
    mov r0,#1        @ is prime
    b 100f
90:
    mov r0,#0        @ no prime
100:                 @ fin standard de la fonction 
    pop {r1-r6,lr}   @ restaur des registres
    bx lr            @ retour de la fonction en utilisant lr 
/********************************************************/
/*   Calcul modulo de b puissance e modulo m  */
/*    Exemple 4 puissance 13 modulo 497 = 445         */
/*                                             */
/********************************************************/
/* r0  nombre  */
/* r1 exposant */
/* r2 modulo   */
/* r0 return result  */
moduloPuR32:
    push {r1-r7,lr}    @ save registers  
    cmp r0,#0          @ verif <> zero 
    beq 100f
    cmp r2,#0          @ verif <> zero 
    beq 100f           @ TODO: vérifier les cas erreur
1:
    mov r4,r2          @ save modulo
    mov r5,r1          @ save exposant 
    mov r6,r0          @ save base
    mov r3,#1          @ start result

    mov r1,#0          @ division de r0,r1 par r2
    bl division32R
    mov r6,r2          @ base <- remainder
2:
    tst r5,#1          @  exposant even or odd
    beq 3f
    umull r0,r1,r6,r3
    mov r2,r4
    bl division32R
    mov r3,r2          @ result <- remainder
3:
    umull r0,r1,r6,r6
    mov r2,r4
    bl division32R
    mov r6,r2          @ base <- remainder

    lsr r5,#1          @ left shift 1 bit
    cmp r5,#0          @ end ?
    bne 2b
    mov r0,r3
100:                   @ fin standard de la fonction
    pop {r1-r7,lr}     @ restaur des registres
    bx lr              @ retour de la fonction en utilisant lr    

/***************************************************/
/*   division number 64 bits in 2 registers by number 32 bits */
/***************************************************/
/* r0 contains lower part dividende   */
/* r1 contains upper part dividende   */
/* r2 contains divisor   */
/* r0 return lower part quotient    */
/* r1 return upper part quotient    */
/* r2 return remainder               */
division32R:
    push {r3-r9,lr}    @ save registers
    mov r6,#0          @ init upper upper part remainder  !!
    mov r7,r1          @ init upper part remainder with upper part dividende
    mov r8,r0          @ init lower part remainder with lower part dividende
    mov r9,#0          @ upper part quotient 
    mov r4,#0          @ lower part quotient
    mov r5,#32         @ bits number
1:                     @ begin loop
    lsl r6,#1          @ shift upper upper part remainder
    lsls r7,#1         @ shift upper  part remainder
    orrcs r6,#1        
    lsls r8,#1         @ shift lower  part remainder
    orrcs r7,#1
    lsls r4,#1         @ shift lower part quotient
    lsl r9,#1          @ shift upper part quotient
    orrcs r9,#1
                       @ divisor sustract  upper  part remainder
    subs r7,r2
    sbcs  r6,#0        @ and substract carry
    bmi 2f             @ négative ?
    
                       @ positive or equal
    orr r4,#1          @ 1 -> right bit quotient
    b 3f
2:                     @ negative 
    orr r4,#0          @ 0 -> right bit quotient
    adds r7,r2         @ and restaur remainder
    adc  r6,#0 
3:
    subs r5,#1         @ decrement bit size 
    bgt 1b             @ end ?
    mov r0,r4          @ lower part quotient
    mov r1,r9          @ upper part quotient
    mov r2,r7          @ remainder
100:                   @ function end
    pop {r3-r9,lr}     @ restaur registers
    bx lr  


/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
.include "../affichage.inc"
 number 1           totient 1             is prime.
 number 2           totient 1             is prime.
 number 3           totient 2             is prime.
 number 4           totient 2
 number 5           totient 4             is prime.
 number 6           totient 2
 number 7           totient 6             is prime.
 number 8           totient 4
 number 9           totient 6
 number 10          totient 4
 number 11          totient 10            is prime.
 number 12          totient 4
 number 13          totient 12            is prime.
 number 14          totient 6
 number 15          totient 8
 number 16          totient 8
 number 17          totient 16            is prime.
 number 18          totient 6
 number 19          totient 18            is prime.
 number 20          totient 8
 number 21          totient 12
 number 22          totient 10
 number 23          totient 22            is prime.
 number 24          totient 8
 number 25          totient 20
Number of primes to 100         : 25
Number of primes to 1000        : 168
Number of primes to 10000       : 1229
Number of primes to 100000      : 9592

Arturo

totient: function [n][
    tot: new n
    i: 2
    while -> n >= i * i [
        if 0 = n % i [
            while -> 0 = n % i -> n: n / i
            'tot - tot / i
        ]
        if 2 = i -> i: 1
        'i + 2
    ]
    if n > 1 -> 'tot - tot / n
    return tot
]

primes: 0
loop 1..100000 'i [
    t: totient i
    prime?: 1 = i - t
    if i < 26 [
        prints ~« Φ(|pad.with:`0` to :string i 2|) = |pad to :string t 2|
        if prime? -> prints ", prime"
        print ""
    ]
    if 50 = i -> print ""
    if in? i [100 1000 10000 100000] -> print ~« |primes| primes =< |i|
    if prime? -> 'primes + 1
]
Output:
Φ(01) =  1
Φ(02) =  1, prime
Φ(03) =  2, prime
Φ(04) =  2
Φ(05) =  4, prime
Φ(06) =  2
Φ(07) =  6, prime
Φ(08) =  4
Φ(09) =  6
Φ(10) =  4
Φ(11) = 10, prime
Φ(12) =  4
Φ(13) = 12, prime
Φ(14) =  6
Φ(15) =  8
Φ(16) =  8
Φ(17) = 16, prime
Φ(18) =  6
Φ(19) = 18, prime
Φ(20) =  8
Φ(21) = 12
Φ(22) = 10
Φ(23) = 22, prime
Φ(24) =  8
Φ(25) = 20

25 primes =< 100
168 primes =< 1000
1229 primes =< 10000
9592 primes =< 100000

AutoHotkey

global cptext := a_tab "Nr" a_tab "Phi" a_tab "Prime?`n---------------------------------------------`n"

divisores(num)
{
	serie := ""
	loop % num
		if !mod(num,a_index)
			serie .= a_index ","
	return serie
}

gcd(serieA,serieB)
{
	emComum := 0 
	loop,parse,serieA,csv
		if A_LoopField in %serieB%
			emComum += 1
	return emComum
}	
		
principal(voltas,phi:=0)
{
loop %voltas%
{
cp := A_Index
cpcount := 0
numA := divisores(cp)
loop % a_index
	{
		numA := divisores(cp)
		numB := divisores(A_Index)
		fim := gcd(numA,numB)
		if (fim = 1)
			cpcount += 1
	}		
if (cpcount = cp-1)
	{
		if phi
			cptext .= a_tab cp a_tab cpcount a_tab "1`n"
		totalPrimes += 1
	}
else
	cptext .= a_tab cp a_tab cpcount a_tab "0`n"
}
return totalPrimes
}

totalPrimes := principal(25,1)
msgbox % cptext "`n`ntotal primes  =  " totalPrimes ; Number 1 is a prime number ? If yes, add 1 to totalPrimes
totalPrimes := principal(100)
msgbox % "total primes in 1 .. 100  =  " totalPrimes
totalPrimes := principal(1000)							; caution... pure gcd method
msgbox % "total primes in 1 .. 1000  =  " totalPrimes  ; takes 3 minutes or more 
;totalPrimes := principal(10000)
;msgbox % "total primes in 1 .. 10000  =  " totalPrimes
ExitApp
Output:
---------------------------
Totient function.ahk
---------------------------
	Nr	Phi	Prime?
---------------------------------------------
	1	1	0
	2	1	1
	3	2	1
	4	2	0
	5	4	1
	6	2	0
	7	6	1
	8	4	0
	9	6	0
	10	4	0
	11	10	1
	12	4	0
	13	12	1
	14	6	0
	15	8	0
	16	8	0
	17	16	1
	18	6	0
	19	18	1
	20	8	0
	21	12	0
	22	10	0
	23	22	1
	24	8	0
	25	20	0

total primes  =  9
---------------------------
OK   
---------------------------
total primes in 1 .. 100  =  25
---------------------------
OK   
---------------------------
total primes in 1 .. 1000  =  168
---------------------------
OK

AWK

# syntax: GAWK -f TOTIENT_FUNCTION.AWK
BEGIN {
    print(" N Phi isPrime")
    for (n=1; n<=1000000; n++) {
      tot = totient(n)
      if (n-1 == tot) {
        count++
      }
      if (n <= 25) {
        printf("%2d %3d %s\n",n,tot,(n-1==tot)?"true":"false")
        if (n == 25) {
          printf("\n  Limit PrimeCount\n")
          printf("%7d %10d\n",n,count)
        }
      }
      else if (n ~ /^100+$/) {
        printf("%7d %10d\n",n,count)
      }
    }
    exit(0)
}
function totient(n,  i,tot) {
    tot = n
    for (i=2; i*i<=n; i+=2) {
      if (n % i == 0) {
        while (n % i == 0) {
          n /= i
        }
        tot -= tot / i
      }
      if (i == 2) {
        i = 1
      }
    }
    if (n > 1) {
      tot -= tot / n
    }
    return(tot)
}
Output:
 N Phi isPrime
 1   1 false
 2   1 true
 3   2 true
 4   2 false
 5   4 true
 6   2 false
 7   6 true
 8   4 false
 9   6 false
10   4 false
11  10 true
12   4 false
13  12 true
14   6 false
15   8 false
16   8 false
17  16 true
18   6 false
19  18 true
20   8 false
21  12 false
22  10 false
23  22 true
24   8 false
25  20 false

  Limit PrimeCount
     25          9
    100         25
   1000        168
  10000       1229
 100000       9592
1000000      78498

BASIC

10 DEFINT A-Z: DIM B$(2): B$(0)="No": B$(1)="Yes"
20 PRINT " N  Totient  Prime"
30 FOR N=1 TO 25
40 GOSUB 200 
50 P=-(T=N-1)
60 C=C+P
70 PRINT USING "##  #######  \   \";N;T;B$(P)
80 NEXT N
90 F$="Number of primes up to ######: ####"
100 PRINT USING F$;25;C
110 FOR N=26 TO 10000
120 GOSUB 200
130 C=C-(T=N-1)
140 IF N=100 OR N=1000 OR N=10000 THEN PRINT USING F$;N;C
150 NEXT N
160 END
200 REM T = TOTIENT(N)
210 T=N: Z=N
220 I=2: GOSUB 270
230 I=3
240 IF I*I<=Z THEN GOSUB 270: I=I+2: GOTO 240
250 IF Z>1 THEN T=T-T\Z
260 RETURN
270 IF Z MOD I<>0 THEN RETURN
280 IF Z MOD I=0 THEN Z = Z\I: GOTO 280
290 T = T-T\I
300 RETURN
Output:
 N  Totient  Prime
 1        1  No
 2        1  Yes
 3        2  Yes
 4        2  No
 5        4  Yes
 6        2  No
 7        6  Yes
 8        4  No
 9        6  No
10        4  No
11       10  Yes
12        4  No
13       12  Yes
14        6  No
15        8  No
16        8  No
17       16  Yes
18        6  No
19       18  Yes
20        8  No
21       12  No
22       10  No
23       22  Yes
24        8  No
25       20  No
Number of primes up to     25:    9
Number of primes up to    100:   25
Number of primes up to   1000:  168
Number of primes up to  10000: 1229

BCPL

Translation of: C
get "libhdr"

let totient(n) = valof
$(  let tot = n and i = 2
    while i*i <= n
    $(  if n rem i = 0
        $(  while n rem i = 0 do n := n / i
            tot := tot - tot/i
        $)
        if i=2 then i:=1
        i := i+2
    $)
    resultis n>1 -> tot-tot/n, tot
$)

let start() be
$(  let count = 0
    writes(" N  Totient  Prime*N")
    for n = 1 to 25
    $(  let tot = totient(n)
        let prime = n-1 = tot
        if prime then count := count + 1
        writef("%I2  %I7  %S*N", n, tot, prime -> "  Yes", "   No")
    $)
    writef("Number of primes up to %I6: %I4*N", 25, count)
    for n = 26 to 10000
    $(  if totient(n) = n-1 then count := count + 1
        if n = 100 | n = 1000 | n = 10000 then
            writef("Number of primes up to %I6: %I4*N", n, count)
    $)
$)
Output:
 N  Totient  Prime
 1        1     No
 2        1    Yes
 3        2    Yes
 4        2     No
 5        4    Yes
 6        2     No
 7        6    Yes
 8        4     No
 9        6     No
10        4     No
11       10    Yes
12        4     No
13       12    Yes
14        6     No
15        8     No
16        8     No
17       16    Yes
18        6     No
19       18    Yes
20        8     No
21       12     No
22       10     No
23       22    Yes
24        8     No
25       20     No
Number of primes up to     25:    9
Number of primes up to    100:   25
Number of primes up to   1000:  168
Number of primes up to  10000: 1229

BQN

GCD function is taken from BQNcrate.

The totient function is similar to APL and J, except it is made as a train. An explicit version of Totient is {+´1=𝕩GCD¨1+↕𝕩}

GCD  {𝕨(|𝕊(>0))𝕩}
Totient  +´1=⊢GCD¨1+↕
Usage:
   Totient¨1+↕25
 1 1 2 2 4 2 6 4 6 4 10 4 12 6 8 8 16 6 18 8 12 10 22 8 20 

   "Number""Totient""Prime?"˘{𝕩(⊢≍(𝕩-1)=)Totient¨𝕩}1+↕25
┌─                                                                             
 "Number"  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25  
  "Totient" 1 1 2 2 4 2 6 4 6 4  10 4  12 6  8  8  16 6  18 8  12 10 22 8  20  
  "Prime?"  0 1 1 0 1 0 1 0 0 0  1  0  1  0  0  0  1  0  1  0  0  0  1  0  0   
                                                                              

The primes library from bqn-libs includes a Totient function based on factoring that's much faster for numbers in the hundreds and above.

C

Translation of the second Go example

/*Abhishek Ghosh, 7th December 2018*/

#include<stdio.h>

int totient(int n){
	int tot = n,i;
	
	for(i=2;i*i<=n;i+=2){
		if(n%i==0){
			while(n%i==0)
				n/=i;
			tot-=tot/i;
		}
		
		if(i==2)
			i=1;
	}
	
	if(n>1)
		tot-=tot/n;
	
	return tot;
}

int main()
{
	int count = 0,n,tot;
	
	printf(" n    %c   prime",237);
        printf("\n---------------\n");
	
	for(n=1;n<=25;n++){
		tot = totient(n);
		
		if(n-1 == tot)
			count++;
		
		printf("%2d   %2d   %s\n", n, tot, n-1 == tot?"True":"False");
	}
	
	printf("\nNumber of primes up to %6d =%4d\n", 25,count);
	
	for(n = 26; n <= 100000; n++){
        tot = totient(n);
        if(tot == n-1)
			count++;
        
        if(n == 100 || n == 1000 || n%10000 == 0){
            printf("\nNumber of primes up to %6d = %4d\n", n, count);
        }
    }
	
	return 0;
}

Output :

 n    φ   prime
---------------
 1    1   False
 2    1   True
 3    2   True
 4    2   False
 5    4   True
 6    2   False
 7    6   True
 8    4   False
 9    6   False
10    4   False
11   10   True
12    4   False
13   12   True
14    6   False
15    8   False
16    8   False
17   16   True
18    6   False
19   18   True
20    8   False
21   12   False
22   10   False
23   22   True
24    8   False
25   20   False

Number of primes up to     25 =   9

Number of primes up to    100 =   25

Number of primes up to   1000 =  168

Number of primes up to  10000 = 1229

Number of primes up to  20000 = 2262

Number of primes up to  30000 = 3245

Number of primes up to  40000 = 4203

Number of primes up to  50000 = 5133

Number of primes up to  60000 = 6057

Number of primes up to  70000 = 6935

Number of primes up to  80000 = 7837

Number of primes up to  90000 = 8713

Number of primes up to 100000 = 9592

C#

using static System.Console;
using static System.Linq.Enumerable;

public class Program
{
    static void Main()
    {
        for (int i = 1; i <= 25; i++) {
            int t = Totient(i);
            WriteLine(i + "\t" + t + (t == i - 1 ? "\tprime" : ""));
        }
        WriteLine();
        for (int i = 100; i <= 100_000; i *= 10) {
            WriteLine($"{Range(1, i).Count(x => Totient(x) + 1 == x):n0} primes below {i:n0}");
        }
    }

    static int Totient(int n) {
        if (n < 3) return 1;
        if (n == 3) return 2;

        int totient = n;

        if ((n & 1) == 0) {
            totient >>= 1;
            while (((n >>= 1) & 1) == 0) ;
        }

        for (int i = 3; i * i <= n; i += 2) {
            if (n % i == 0) {
                totient -= totient / i;
                while ((n /= i) % i == 0) ;
            }
        }
        if (n > 1) totient -= totient / n;
        return totient;
    }
}
Output:
1	1
2	1	prime
3	2	prime
4	2
5	4	prime
6	2
7	6	prime
8	4
9	6
10	4
11	10	prime
12	4
13	12	prime
14	6
15	8
16	8
17	16	prime
18	6
19	18	prime
20	8
21	12
22	10
23	22	prime
24	8
25	20

25 primes below 100
168 primes below 1,000
1,229 primes below 10,000
9,592 primes below 100,000

C++

Translation of: Java
#include <cassert>
#include <iomanip>
#include <iostream>
#include <vector>

class totient_calculator {
public:
    explicit totient_calculator(int max) : totient_(max + 1) {
        for (int i = 1; i <= max; ++i)
            totient_[i] = i;
        for (int i = 2; i <= max; ++i) {
            if (totient_[i] < i)
                continue;
            for (int j = i; j <= max; j += i)
                totient_[j] -= totient_[j] / i;
        }
    }
    int totient(int n) const {
        assert (n >= 1 && n < totient_.size());
        return totient_[n];
    }
    bool is_prime(int n) const {
        return totient(n) == n - 1;
    }
private:
    std::vector<int> totient_;
};

int count_primes(const totient_calculator& tc, int min, int max) {
    int count = 0;
    for (int i = min; i <= max; ++i) {
        if (tc.is_prime(i))
            ++count;
    }
    return count;
}

int main() {
    const int max = 10000000;
    totient_calculator tc(max);
    std::cout << " n  totient  prime?\n";
    for (int i = 1; i <= 25; ++i) {
        std::cout << std::setw(2) << i
            << std::setw(9) << tc.totient(i)
            << std::setw(8) << (tc.is_prime(i) ? "yes" : "no") << '\n';
    }
    for (int n = 100; n <= max; n *= 10) {
        std::cout << "Count of primes up to " << n << ": "
            << count_primes(tc, 1, n) << '\n';
    }
    return 0;
}
Output:
 n  totient  prime?
 1        1      no
 2        1     yes
 3        2     yes
 4        2      no
 5        4     yes
 6        2      no
 7        6     yes
 8        4      no
 9        6      no
10        4      no
11       10     yes
12        4      no
13       12     yes
14        6      no
15        8      no
16        8      no
17       16     yes
18        6      no
19       18     yes
20        8      no
21       12      no
22       10      no
23       22     yes
24        8      no
25       20      no
Count of primes up to 100: 25
Count of primes up to 1000: 168
Count of primes up to 10000: 1229
Count of primes up to 100000: 9592
Count of primes up to 1000000: 78498
Count of primes up to 10000000: 664579

CLU

Translation of: C
totient = proc (n: int) returns (int)
    tot: int := n

    i: int := 2
    while i*i <= n do
        if n//i = 0 then
            while n//i = 0 do
                n := n/i
            end
            tot := tot-tot/i
        end
        if i=2 then i:=1 end
        i := i+2
    end
    if n>1 then
        tot := tot-tot/n
    end
    return(tot)
end totient

start_up = proc ()
    po: stream := stream$primary_output()
    count: int := 0

    stream$putl(po, " N  Totient  Prime")
    for n: int in int$from_to(1, 25) do
        tot: int := totient(n)
        stream$putright(po, int$unparse(n), 2)
        stream$putright(po, int$unparse(tot), 9)
        if n-1 = tot then
            stream$putright(po, "Yes", 7)
            count := count + 1
        else
            stream$putright(po, "No", 7)
        end
        stream$putl(po, "")
    end

    stream$putl(po, "Number of primes up to 25:\t" || int$unparse(count))
    for n: int in int$from_to(26, 100000) do
        if totient(n) = n-1 then
            count := count + 1
        end
        if n = 100 cor n = 1000 cor n // 10000 = 0 then
            stream$putl(po, "Number of primes up to "
                        || int$unparse(n) || ":\t"
                        || int$unparse(count))
        end
    end
end start_up
Output:
 N  Totient  Prime
 1        1     No
 2        1    Yes
 3        2    Yes
 4        2     No
 5        4    Yes
 6        2     No
 7        6    Yes
 8        4     No
 9        6     No
10        4     No
11       10    Yes
12        4     No
13       12    Yes
14        6     No
15        8     No
16        8     No
17       16    Yes
18        6     No
19       18    Yes
20        8     No
21       12     No
22       10     No
23       22    Yes
24        8     No
25       20     No
Number of primes up to 25:      9
Number of primes up to 100:     25
Number of primes up to 1000:    168
Number of primes up to 10000:   1229
Number of primes up to 20000:   2262
Number of primes up to 30000:   3245
Number of primes up to 40000:   4203
Number of primes up to 50000:   5133
Number of primes up to 60000:   6057
Number of primes up to 70000:   6935
Number of primes up to 80000:   7837
Number of primes up to 90000:   8713
Number of primes up to 100000:  9592

COBOL

       IDENTIFICATION DIVISION.
       PROGRAM-ID. TOTIENT-FUNCTION.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 TOTIENT-CALCULATION.
          03 N               PIC 9(6).
          03 TOTIENT         PIC 9(6).
          03 DIVISOR         PIC 9(6).
          03 DIV-SQUARE      PIC 9(6).
          03 MODULUS         PIC 9(6).

       01 LOOP-VARS.
          03 PRIME-COUNT     PIC 9(4).
          03 CURRENT-N       PIC 9(6).
          03 PRIME-TOTIENT   PIC 9(6).

       01 OUTPUTFORMAT.
          03 HEADER          PIC X(20) VALUE " N  Totient  Prime?".
          03 TOTIENT-ROW.
             05 OUT-N        PIC Z9.
             05 FILLER       PIC XX VALUE SPACES.
             05 OUT-TOTIENT  PIC Z(6)9.
             05 FILLER       PIC XX VALUE SPACES.
             05 OUT-PRIME    PIC X(5).
          03 PRIME-COUNT-ROW.
             05 FILLER       PIC X(22) VALUE "Number of primes up to".
             05 OUT-PRMTO    PIC Z(5)9.
             05 FILLER       PIC XX VALUE ": ".
             05 OUT-PRMCNT   PIC ZZZ9.

       PROCEDURE DIVISION.
       BEGIN.
           MOVE ZERO TO PRIME-COUNT.
           DISPLAY HEADER.
           PERFORM SHOW-SMALL-TOTIENT
               VARYING CURRENT-N FROM 1 BY 1
               UNTIL CURRENT-N IS GREATER THAN 25.
           MOVE 25 TO OUT-PRMTO.
           MOVE PRIME-COUNT TO OUT-PRMCNT.
           DISPLAY PRIME-COUNT-ROW.
           PERFORM COUNT-PRIMES
               VARYING CURRENT-N FROM 26 BY 1
               UNTIL CURRENT-N IS GREATER THAN 10000.
           STOP RUN.

       SHOW-SMALL-TOTIENT.
           MOVE CURRENT-N TO N.
           PERFORM CALCULATE-TOTIENT.
           MOVE CURRENT-N TO OUT-N.
           MOVE TOTIENT TO OUT-TOTIENT.
           MOVE "No" TO OUT-PRIME.
           SUBTRACT 1 FROM CURRENT-N GIVING PRIME-TOTIENT.
           IF TOTIENT IS EQUAL TO PRIME-TOTIENT,
               MOVE "Yes" TO OUT-PRIME,
               ADD 1 TO PRIME-COUNT.
           DISPLAY TOTIENT-ROW.

       COUNT-PRIMES.
           MOVE CURRENT-N TO N.
           PERFORM CALCULATE-TOTIENT.
           SUBTRACT 1 FROM CURRENT-N GIVING PRIME-TOTIENT.
           IF TOTIENT IS EQUAL TO PRIME-TOTIENT, ADD 1 TO PRIME-COUNT.
           IF CURRENT-N IS EQUAL TO 100 OR 1000 OR 10000,
               MOVE CURRENT-N TO OUT-PRMTO,
               MOVE PRIME-COUNT TO OUT-PRMCNT,
               DISPLAY PRIME-COUNT-ROW.

       CALCULATE-TOTIENT.
           MOVE N TO TOTIENT.
           MOVE 2 TO DIVISOR.
           MOVE 4 TO DIV-SQUARE.
           PERFORM DIVIDE-STEP.
           PERFORM DIVIDE-STEP
               VARYING DIVISOR FROM 3 BY 2
               UNTIL DIV-SQUARE IS GREATER THAN N.
           IF N IS GREATER THAN 1,
               COMPUTE TOTIENT = TOTIENT - TOTIENT / N.

       DIVIDE-STEP.
           MULTIPLY DIVISOR BY DIVISOR GIVING DIV-SQUARE.
           DIVIDE N BY DIVISOR GIVING MODULUS.
           MULTIPLY DIVISOR BY MODULUS.
           SUBTRACT MODULUS FROM N GIVING MODULUS.
           IF MODULUS IS ZERO,
               PERFORM DIVIDE-OUT UNTIL MODULUS IS NOT ZERO,
               COMPUTE TOTIENT = TOTIENT - TOTIENT / DIVISOR.

       DIVIDE-OUT.
           DIVIDE DIVISOR INTO N.
           DIVIDE N BY DIVISOR GIVING MODULUS.
           MULTIPLY DIVISOR BY MODULUS.
           SUBTRACT MODULUS FROM N GIVING MODULUS.
Output:
 N  Totient  Prime?
 1        1  No
 2        1  Yes
 3        2  Yes
 4        2  No
 5        4  Yes
 6        2  No
 7        6  Yes
 8        4  No
 9        6  No
10        4  No
11       10  Yes
12        4  No
13       12  Yes
14        6  No
15        8  No
16        8  No
17       16  Yes
18        6  No
19       18  Yes
20        8  No
21       12  No
22       10  No
23       22  Yes
24        8  No
25       20  No
Number of primes up to    25:    9
Number of primes up to   100:   25
Number of primes up to  1000:  168
Number of primes up to 10000: 1229

Cowgol

Translation of: C
include "cowgol.coh";

sub totient(n: uint32): (tot: uint32) is
    tot := n;

    var i: uint32 := 2;
    while i*i <= n loop
        if n%i == 0 then
            while n%i == 0 loop
                n := n/i;
            end loop;
            tot := tot - tot/i;
        end if;
        if i == 2 then
            i := 1;
        end if;
        i := i + 2;
    end loop;

    if n > 1 then
        tot := tot - tot/n;
    end if;
end sub;

var count: uint16 := 0;

print("N\tTotient\tPrime\n");
var n: uint32 := 1;
while n <= 25 loop
    var tot := totient(n);
    print_i32(n);
    print_char('\t');
    print_i32(tot);
    print_char('\t');
    if n-1 == tot then
        count := count + 1;
        print("Yes\n");
    else
        print("No\n");
    end if;
    n := n + 1;
end loop;

print("Number of primes up to 25:\t");
print_i16(count);
print_nl();

while n <= 100000 loop
    tot := totient(n);
    if n-1 == tot then
        count := count + 1;
    end if;
    if n == 100 or n == 1000 or n % 10000 == 0 then
        print("Number of primes up to ");
        print_i32(n);
        print(":\t");
        print_i16(count);
        print_nl();
    end if;
    n := n + 1;
end loop;
Output:
N       Totient Prime
1       1       No
2       1       Yes
3       2       Yes
4       2       No
5       4       Yes
6       2       No
7       6       Yes
8       4       No
9       6       No
10      4       No
11      10      Yes
12      4       No
13      12      Yes
14      6       No
15      8       No
16      8       No
17      16      Yes
18      6       No
19      18      Yes
20      8       No
21      12      No
22      10      No
23      22      Yes
24      8       No
25      20      No
Number of primes up to 25:      9
Number of primes up to 100:     25
Number of primes up to 1000:    168
Number of primes up to 10000:   1229
Number of primes up to 20000:   2262
Number of primes up to 30000:   3245
Number of primes up to 40000:   4203
Number of primes up to 50000:   5133
Number of primes up to 60000:   6057
Number of primes up to 70000:   6935
Number of primes up to 80000:   7837
Number of primes up to 90000:   8713
Number of primes up to 100000:  9592

D

Translation of: C
import std.stdio;

int totient(int n) {
    int tot = n;

    for (int i = 2; i * i <= n; i += 2) {
        if (n % i == 0) {
            while (n % i == 0) {
                n /= i;
            }
            tot -= tot / i;
        }
        if (i==2) {
            i = 1;
        }
    }

    if (n > 1) {
        tot -= tot / n;
    }
    return tot;
}

void main() {
    writeln(" n    φ   prime");
    writeln("---------------");

    int count = 0;
    for (int n = 1; n <= 25; n++) {
        int tot = totient(n);

        if (n - 1 == tot) {
            count++;
        }

        writefln("%2d   %2d   %s", n,tot, n - 1 == tot);
    }
    writeln;

    writefln("Number of primes up to %6d = %4d", 25, count);
    for (int n = 26; n <= 100_000; n++) {
        int tot = totient(n);

        if (n - 1 == tot) {
            count++;
        }

        if (n == 100 || n == 1_000 || n % 10_000 == 0) {
            writefln("Number of primes up to %6d = %4d", n, count);
        }
    }
}
Output:
 n    φ   prime
---------------
 1    1   false
 2    1   true
 3    2   true
 4    2   false
 5    4   true
 6    2   false
 7    6   true
 8    4   false
 9    6   false
10    4   false
11   10   true
12    4   false
13   12   true
14    6   false
15    8   false
16    8   false
17   16   true
18    6   false
19   18   true
20    8   false
21   12   false
22   10   false
23   22   true
24    8   false
25   20   false

Number of primes up to     25 =    9
Number of primes up to    100 =   25
Number of primes up to   1000 =  168
Number of primes up to  10000 = 1229
Number of primes up to  20000 = 2262
Number of primes up to  30000 = 3245
Number of primes up to  40000 = 4203
Number of primes up to  50000 = 5133
Number of primes up to  60000 = 6057
Number of primes up to  70000 = 6935
Number of primes up to  80000 = 7837
Number of primes up to  90000 = 8713
Number of primes up to 100000 = 9592

Delphi

See Pascal.

Draco

Translation of: C
proc totient(word n) word:
    word tot, i;
    tot := n;
    i := 2;
    while i*i <= n do
        if n%i = 0 then
            while n%i = 0 do n := n/i od;
            tot := tot - tot/i
        fi;
        if i=2 then i:=1 fi;
        i := i+2
    od;
    if n>1 then
        tot - tot/n
    else
        tot
    fi
corp

proc main() void:
    word count, n, tot;
    bool prime;

    count := 0;
    writeln(" N  Totient  Prime");
    for n from 1 upto 25 do
        tot := totient(n);
        prime := n-1 = tot;
        if prime then count := count+1 fi;
        writeln(n:2, "  ", tot:7, "  ", if prime then "  Yes" else "   No" fi)
    od;
    writeln("Number of primes up to ",25:6,": ",count:4);
    for n from 25 upto 10000 do
        if totient(n) = n-1 then count := count+1 fi;
        if n=100 or n=1000 or n=10000 then
            writeln("Number of primes up to ",n:6,": ",count:4)
        fi
    od
corp
Output:
 N  Totient  Prime
 1        1     No
 2        1    Yes
 3        2    Yes
 4        2     No
 5        4    Yes
 6        2     No
 7        6    Yes
 8        4     No
 9        6     No
10        4     No
11       10    Yes
12        4     No
13       12    Yes
14        6     No
15        8     No
16        8     No
17       16    Yes
18        6     No
19       18    Yes
20        8     No
21       12     No
22       10     No
23       22    Yes
24        8     No
25       20     No
Number of primes up to     25:    9
Number of primes up to    100:   25
Number of primes up to   1000:  168
Number of primes up to  10000: 1229

Dyalect

Translation of: Go
func totient(n) {
    var tot = n
    var i = 2
    while i * i <= n {
        if n % i == 0 {
            while n % i == 0 {
                n /= i
            }
            tot -= tot / i
        }
        if i == 2 {
            i = 1
        }
        i += 2
    }
    if n > 1 {
        tot -= tot / n
    }
    return tot
} 

print("n\tphi\tprime")
var count = 0
for n in 1..25 {
    var tot = totient(n)
    var isPrime = n - 1 == tot
    if isPrime {
        count += 1
    }
    print("\(n)\t\(tot)\t\(isPrime)")
}
print("\nNumber of primes up to 25 \t= \(count)")
for n in 26..100000 {
    var tot = totient(n)
    if tot == n - 1 {
        count += 1
    }
    if n == 100 || n == 1000 || n % 10000 == 0 {
        print("Number of primes up to \(n) \t= \(count)")
    }
}
Output:
n       phi     prime
1       1       false
2       1       true
3       2       true
4       2       false
5       4       true
6       2       false
7       6       true
8       4       false
9       6       false
10      4       false
11      10      true
12      4       false
13      12      true
14      6       false
15      8       false
16      8       false
17      16      true
18      6       false
19      18      true
20      8       false
21      12      false
22      10      false
23      22      true
24      8       false
25      20      false

Number of primes up to 25       = 9
Number of primes up to 100      = 25
Number of primes up to 1000     = 168
Number of primes up to 10000    = 1229
Number of primes up to 20000    = 2262
Number of primes up to 30000    = 3245
Number of primes up to 40000    = 4203
Number of primes up to 50000    = 5133
Number of primes up to 60000    = 6057
Number of primes up to 70000    = 6935
Number of primes up to 80000    = 7837
Number of primes up to 90000    = 8713
Number of primes up to 100000   = 9592

EasyLang

Translation of: AWK
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
.
numfmt 0 3
print "  N Prim Phi"
for n = 1 to 25
   tot = totient n
   x$ = "    "
   if n - 1 = tot
      x$ = " x  "
   .
   print n & x$ & tot
.
print ""
for n = 1 to 100000
   tot = totient n
   if n - 1 = tot
      cnt += 1
   .
   if n = 100 or n = 1000 or n = 10000 or n = 100000
      print n & " - " & cnt & " primes"
   .
.


Factor

USING: combinators formatting io kernel math math.primes.factors
math.ranges sequences ;
IN: rosetta-code.totient-function

: Φ ( n -- m )
    {
        { [ dup 1 < ] [ drop 0 ] }
        { [ dup 1 = ] [ drop 1 ] }
        [
            dup unique-factors
            [ 1 [ 1 - * ] reduce ] [ product ] bi / *
        ]
    } cond ;

: show-info ( n -- )
    [ Φ ] [ swap 2dup - 1 = ] bi ", prime" "" ?
    "Φ(%2d) = %2d%s\n" printf ;

: totient-demo ( -- )
    25 [1,b] [ show-info ] each nl 0 100,000 [1,b] [
        [ dup Φ - 1 = [ 1 + ] when ]
        [ dup { 100 1,000 10,000 100,000 } member? ] bi
        [ dupd "%4d primes <= %d\n" printf ] [ drop ] if
    ] each drop ;

MAIN: totient-demo
Output:
Φ( 1) =  1
Φ( 2) =  1, prime
Φ( 3) =  2, prime
Φ( 4) =  2
Φ( 5) =  4, prime
Φ( 6) =  2
Φ( 7) =  6, prime
Φ( 8) =  4
Φ( 9) =  6
Φ(10) =  4
Φ(11) = 10, prime
Φ(12) =  4
Φ(13) = 12, prime
Φ(14) =  6
Φ(15) =  8
Φ(16) =  8
Φ(17) = 16, prime
Φ(18) =  6
Φ(19) = 18, prime
Φ(20) =  8
Φ(21) = 12
Φ(22) = 10
Φ(23) = 22, prime
Φ(24) =  8
Φ(25) = 20

  25 primes <= 100
 168 primes <= 1000
1229 primes <= 10000
9592 primes <= 100000

FreeBASIC

Translation of: Pascal
#define esPar(n) (((n) And 1) = 0)
#define esImpar(n)  (esPar(n) = 0)

Function Totient(n As Integer) As Integer
    'delta son números no divisibles por 2,3,5
    Dim delta(7) As Integer = {6,4,2,4,2,4,6,2}
    Dim As Integer i, quot, idx, result
    ' div mod por constante es rápido.
    'i = 2
    result = n
    If (2*2 <= n) Then
        If Not(esImpar(n)) Then
            ' eliminar números con factor 2,4,8,16,...
            While Not(esImpar(n))
                n = n \ 2
            Wend
            'eliminar los múltiplos de 2
            result -= result \ 2
        End If
    End If
    'i = 3
    If (3*3 <= n) And (n Mod 3 = 0) Then
        Do
            quot = n \ 3
            If n <> quot*3 Then
                Exit Do
            Else
                n = quot
            End If
        Loop Until false
        result -= result \ 3
    End If
    'i = 5
    If (5*5 <= n) And (n Mod 5 = 0) Then
        Do
            quot = n \ 5
            If n <> quot*5 Then
                Exit Do
            Else
                n = quot
            End If
        Loop Until false
        result -= result \ 5
    End If
    i = 7
    idx = 1
    'i = 7,11,13,17,19,23,29,...,49 ..
    While i*i <= n
        quot = n \ i
        If n = quot*i Then
            Do
                If n <> quot*i Then
                    Exit Do
                Else
                    n = quot
                End If
                quot = n \ i
            Loop Until false
            result -= result \ i
        End If
        i = i + delta(idx)
        idx = (idx+1) And 7
    Wend
    If n > 1 Then result -= result \ n
    Totient = result
End Function

Sub ContandoPrimos(n As Integer)
    Dim As Integer i, cnt = 0
    For i = 1 To n
        If Totient(i) = (i-1) Then cnt += 1
    Next i
    Print Using " #######      ######"; i-1; cnt
End Sub

Function esPrimo(n As Ulongint) As String
    esPrimo = "False"
    If n = 1 then Return "False"
    If (n=2) Or (n=3) Then Return "True"
    If n Mod 2=0 Then Exit Function
    If n Mod 3=0 Then Exit Function
    Dim As Ulongint limite = Sqr(N)+1
    For i As Ulongint = 6 To limite Step 6
        If N Mod (i-1)=0 Then Exit Function
        If N Mod (i+1)=0 Then Exit Function
    Next i
    Return "True"
End Function 

Sub display(n As Integer)
    Dim As Integer idx, phi
    If n = 0 Then Exit Sub
    Print "  n  phi(n)   esPrimo" 
    For idx = 1 To n
        phi = Totient(idx)
        Print Using "###   ###      \   \"; idx; phi; esPrimo(idx)
    Next idx
End Sub

Dim l As Integer
display(25)

Print Chr(10) & "   Limite  Son primos"
ContandoPrimos(25)
l = 100
Do
    ContandoPrimos(l)
    l = l*10
Loop Until l > 1000000
End
Output:
  n  phi(n)   esPrimo
  1     1      False
  2     1      True
  3     2      True
  4     2      False
  5     4      True
  6     2      False
  7     6      True
  8     4      False
  9     6      False
 10     4      False
 11    10      True
 12     4      False
 13    12      True
 14     6      False
 15     8      False
 16     8      False
 17    16      True
 18     6      False
 19    18      True
 20     8      False
 21    12      False
 22    10      False
 23    22      True
 24     8      False
 25    20      False

   Limite  Son primos
      25           9
     100          25
    1000         168
   10000        1229
  100000        9592
 1000000       78498

Fōrmulæ

Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.

Programs in Fōrmulæ are created/edited online in its website.

In this page you can see and run the program(s) related to this task and their results. You can also change either the programs or the parameters they are called with, for experimentation, but remember that these programs were created with the main purpose of showing a clear solution of the task, and they generally lack any kind of validation.

Solution

File:Fōrmulæ - Totient function 01.png

Case 1

File:Fōrmulæ - Totient function 02.png

File:Fōrmulæ - Totient function 03.png

Case 2

File:Fōrmulæ - Totient function 04.png

File:Fōrmulæ - Totient function 05.png

Forth

Translation from C

: totient   \ n -- n' ;
  DUP DUP 2 ?DO     ( tot n ) 
    DUP I DUP * < IF   LEAVE   THEN                     \ for(i=2;i*i<=n;i+=2){
    DUP I MOD 0= IF					\     if(n%i==0){
      BEGIN   DUP I /MOD SWAP 0=   WHILE  ( tot n n/i ) \       while(n%i==0);
        NIP       ( tot n/i )                           \         n/=i;
      REPEAT 
      DROP                    ( tot n  )  \ Remove the new n on exit from loop
      SWAP DUP I / - SWAP 	  ( tot' n )        	\       tot-=tot/i;
    THEN
  2 I 2 = + +LOOP    \  If I = 2 add 1 else add 2 to loop index.  
  DUP 1 > IF   OVER SWAP / -   ELSE   DROP   THEN ;

: bool.  \ f -- ;
  IF   ." True "   ELSE   ." False"   THEN ; 

: count-primes  \ n -- n' ;
  0 SWAP 2 ?DO   I DUP totient 1+ = -   LOOP ;  

: challenge  \ -- ;
  CR ."   n   φ    prime" CR
  26 1 DO 
    I 3 .r
    I totient DUP 4 .r 4 SPACES
    1+ I = bool. CR
  LOOP CR
  100001 100 DO
    ." Number of primes up to " I 6 .R ."  is " I count-primes 4 .R CR 
  I 9 * +LOOP  ;
Output:
challenge

  n   φ    prime
  1   1    False
  2   1     True
  3   2     True
  4   2    False
  5   4     True
  6   2    False
  7   6     True
  8   4    False
  9   6    False
 10   4    False
 11  10     True
 12   4    False
 13  12     True
 14   6    False
 15   8    False
 16   8    False
 17  16     True
 18   6    False
 19  18     True
 20   8    False
 21  12    False
 22  10    False
 23  22     True
 24   8    False
 25  20    False

Number of primes up to    100 is   25
Number of primes up to   1000 is  168
Number of primes up to  10000 is 1229
Number of primes up to 100000 is 9592

Go

Results for the larger values of n are very slow to emerge.

package main

import "fmt"

func gcd(n, k int) int {
    if n < k || k < 1 {
        panic("Need n >= k and k >= 1")
    }

    s := 1
    for n&1 == 0 && k&1 == 0 {
        n >>= 1
        k >>= 1
        s <<= 1
    }

    t := n
    if n&1 != 0 {
        t = -k
    }
    for t != 0 {
        for t&1 == 0 {
            t >>= 1
        }
        if t > 0 {
            n = t
        } else {
            k = -t
        }
        t = n - k
    }
    return n * s
}

func totient(n int) int {
    tot := 0
    for k := 1; k <= n; k++ {
        if gcd(n, k) == 1 {
            tot++
        }
    }
    return tot
}

func main() {
    fmt.Println(" n  phi   prime")
    fmt.Println("---------------")
    count := 0
    for n := 1; n <= 25; n++ {
        tot := totient(n)
        isPrime := n-1 == tot
        if isPrime {
            count++
        }
        fmt.Printf("%2d   %2d   %t\n", n, tot, isPrime)
    }
    fmt.Println("\nNumber of primes up to 25     =", count)
    for n := 26; n <= 100000; n++ {
        tot := totient(n)
        if tot == n-1 {
            count++
        }
        if n == 100 || n == 1000 || n%10000 == 0 {
            fmt.Printf("\nNumber of primes up to %-6d = %d\n", n, count)
        }
    }
}
Output:
 n  phi   prime
---------------
 1    1   false
 2    1   true
 3    2   true
 4    2   false
 5    4   true
 6    2   false
 7    6   true
 8    4   false
 9    6   false
10    4   false
11   10   true
12    4   false
13   12   true
14    6   false
15    8   false
16    8   false
17   16   true
18    6   false
19   18   true
20    8   false
21   12   false
22   10   false
23   22   true
24    8   false
25   20   false

Number of primes up to 25     = 9

Number of primes up to 100    = 25

Number of primes up to 1000   = 168

Number of primes up to 10000  = 1229

Number of primes up to 20000  = 2262

Number of primes up to 30000  = 3245

Number of primes up to 40000  = 4203

Number of primes up to 50000  = 5133

Number of primes up to 60000  = 6057

Number of primes up to 70000  = 6935

Number of primes up to 80000  = 7837

Number of primes up to 90000  = 8713

Number of primes up to 100000 = 9592

The following much quicker version (runs in less than 150 ms on my machine) uses Euler's product formula rather than repeated invocation of the gcd function to calculate the totient:

package main

import "fmt"

func totient(n int) int {
    tot := n
    for i := 2; i*i <= n; i += 2 {
        if n%i == 0 {
            for n%i == 0 {
                n /= i
            }
            tot -= tot / i
        }
        if i == 2 {
            i = 1
        }
    }
    if n > 1 {
        tot -= tot / n
    }
    return tot
} 
 
func main() {
    fmt.Println(" n  phi   prime")
    fmt.Println("---------------")
    count := 0
    for n := 1; n <= 25; n++ {
        tot := totient(n)
        isPrime := n-1 == tot
        if isPrime {
            count++
        }
        fmt.Printf("%2d   %2d   %t\n", n, tot, isPrime)
    }
    fmt.Println("\nNumber of primes up to 25     =", count)
    for n := 26; n <= 100000; n++ {
        tot := totient(n)
        if tot == n-1 {
            count++
        }
        if n == 100 || n == 1000 || n%10000 == 0 {
            fmt.Printf("\nNumber of primes up to %-6d = %d\n", n, count)
        }
    }    
}

The output is the same as before.

Haskell

Translation of: C
{-# LANGUAGE BangPatterns #-}

import Control.Monad (when)
import Data.Bool (bool)

totient
  :: (Integral a)
  => a -> a
totient n
  | n == 0 = 1 -- by definition phi(0) = 1
  | n < 0 = totient (-n) -- phi(-n) is taken to be equal to phi(n)
  | otherwise = loop n n 2 --
  where
    loop !m !tot !i
      | i * i > m = bool tot (tot - (tot `div` m)) (1 < m)
      | m `mod` i == 0 = loop m_ tot_ i_
      | otherwise = loop m tot i_
      where
        i_
          | i == 2 = 3
          | otherwise = 2 + i
        m_ = nextM m
        tot_ = tot - (tot `div` i)
        nextM !x
          | x `mod` i == 0 = nextM $ x `div` i
          | otherwise = x

main :: IO ()
main = do
  putStrLn "n\tphi\tprime\n---------------------"
  let loop !i !count
        | i >= 10 ^ 6 = return ()
        | otherwise = do
          let i_ = succ i
              tot = totient i_
              isPrime = tot == pred i_
              count_
                | isPrime = succ count
                | otherwise = count
          when (25 >= i_) $
            putStrLn $ show i_ ++ "\t" ++ show tot ++ "\t" ++ show isPrime
          when
            (i_ `elem`
             25 :
             [ 10 ^ k
             | k <- [2 .. 6] ]) $
            putStrLn $ "Number of primes up to " ++ show i_ ++ " = " ++ show count_
          loop (i + 1) count_
  loop 0 0
Output:
n       phi     prime
---------------------
1       1       False
2       1       True 
3       2       True 
4       2       False
5       4       True 
6       2       False
7       6       True
8       4       False
9       6       False
10      4       False
11      10      True
12      4       False
13      12      True
14      6       False
15      8       False
16      8       False
17      16      True
18      6       False
19      18      True
20      8       False
21      12      False
22      10      False
23      22      True
24      8       False
25      20      False
Number of primes up to 25 = 9
Number of primes up to 100 = 25
Number of primes up to 1000 = 168
Number of primes up to 10000 = 1229
Number of primes up to 100000 = 9592
Number of primes up to 1000000 = 78498

J

  nth_prime =: p:   NB. 2 is the zeroth prime
   totient =: 5&p:
   primeQ =:  1&p:

   NB. first row contains the integer
   NB. second row             totient
   NB. third                  1 iff prime
   (, totient ,: primeQ) >: i. 25
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
1 1 2 2 4 2 6 4 6  4 10  4 12  6  8  8 16  6 18  8 12 10 22  8 20
0 1 1 0 1 0 1 0 0  0  1  0  1  0  0  0  1  0  1  0  0  0  1  0  0
   

   NB. primes first exceeding the limits
   [&.:(p:inv) 10 ^ 2 + i. 4
101 1009 10007 100003

   p:inv 101 1009 10007 100003
25 168 1229 9592
   
   NB. limit and prime count
   (,. p:inv) 10 ^ 2 + i. 5
   100    25
  1000   168
 10000  1229
100000  9592
   1e6 78498

Java

Efficiently pre-compute all needed values of phi up to 10,000,000 in .344 sec.

public class TotientFunction {

    public static void main(String[] args) {
        computePhi();
        System.out.println("Compute and display phi for the first 25 integers.");
        System.out.printf("n  Phi  IsPrime%n");
        for ( int n = 1 ; n <= 25 ; n++ ) {
            System.out.printf("%2d  %2d  %b%n", n, phi[n], (phi[n] == n-1));
        }
        for ( int i = 2 ; i < 8 ; i++ ) {
            int max = (int) Math.pow(10, i);
            System.out.printf("The count of the primes up to %,10d = %d%n", max, countPrimes(1, max));
        }
    }
    
    private static int countPrimes(int min, int max) {
        int count = 0;
        for ( int i = min ; i <= max ; i++ ) {
            if ( phi[i] == i-1 ) {
                count++;
            }
        }
        return count;
    }

    private static final int max = 10000000;
    private static final int[] phi = new int[max+1];

    private static final void computePhi() {
        for ( int i = 1 ; i <= max ; i++ ) {
            phi[i] = i;
        }
        for ( int i = 2 ; i <= max ; i++ ) {
            if (phi[i] < i) continue;
            for ( int j = i ; j <= max ; j += i ) {
                phi[j] -= phi[j] / i;
            }
        }
    }

}
Output:
Compute and display phi for the first 25 integers.
n  Phi  IsPrime
 1   1  false
 2   1  true
 3   2  true
 4   2  false
 5   4  true
 6   2  false
 7   6  true
 8   4  false
 9   6  false
10   4  false
11  10  true
12   4  false
13  12  true
14   6  false
15   8  false
16   8  false
17  16  true
18   6  false
19  18  true
20   8  false
21  12  false
22  10  false
23  22  true
24   8  false
25  20  false
The count of the primes up to        100 = 25
The count of the primes up to      1,000 = 168
The count of the primes up to     10,000 = 1229
The count of the primes up to    100,000 = 9592
The count of the primes up to  1,000,000 = 78498
The count of the primes up to 10,000,000 = 664579

jq

Works with: jq
# jq optimizes the recursive call of _gcd in the following:
def gcd(a;b):
  def _gcd:
    if .[1] != 0 then [.[1], .[0] % .[1]] | _gcd else .[0] end;
  [a,b] | _gcd ;

def count(s): reduce s as $x (0; .+1);

def totient:
  . as $n
  | count( range(0; .) | select( gcd($n; .) == 1) );

# input: determines the maximum via range(0; .)
# and so may be `infinite`
def primes_via_totient:
  range(0; .) | select(totient == . - 1);

The tasks

def task:
  def task1($n):
    range(1;$n)
    | totient as $totient
    | {i: ., $totient, isprime: ($totient == ( . - 1 ))};

  task1(26);

def onepass:
  reduce (10000 | primes_via_totient) as $p ({};
      if $p < 10000
      then .["10^4"] += 1
      | if $p < 1000
        then .["10^3"] += 1
        | if $p < 100
          then .["10^2"] += 1
          else . end else . end else . end) ;

task, "\nCounts of primes up to the given limits:", onepass
Output:
{"i":1,"totient":1,"isprime":false}
{"i":2,"totient":1,"isprime":true}
{"i":3,"totient":2,"isprime":true}
{"i":4,"totient":2,"isprime":false}
{"i":5,"totient":4,"isprime":true}
{"i":6,"totient":2,"isprime":false}
{"i":7,"totient":6,"isprime":true}
{"i":8,"totient":4,"isprime":false}
{"i":9,"totient":6,"isprime":false}
{"i":10,"totient":4,"isprime":false}
{"i":11,"totient":10,"isprime":true}
{"i":12,"totient":4,"isprime":false}
{"i":13,"totient":12,"isprime":true}
{"i":14,"totient":6,"isprime":false}
{"i":15,"totient":8,"isprime":false}
{"i":16,"totient":8,"isprime":false}
{"i":17,"totient":16,"isprime":true}
{"i":18,"totient":6,"isprime":false}
{"i":19,"totient":18,"isprime":true}
{"i":20,"totient":8,"isprime":false}
{"i":21,"totient":12,"isprime":false}
{"i":22,"totient":10,"isprime":false}
{"i":23,"totient":22,"isprime":true}
{"i":24,"totient":8,"isprime":false}
{"i":25,"totient":20,"isprime":false}

Counts of primes up to the given limits:
{"10^4":1229,"10^3":168,"10^2":25}

Julia

Translation of: Python
φ(n) = sum(1 for k in 1:n if gcd(n, k) == 1)
 
is_prime(n) = φ(n) == n - 1

function runphitests()
    for n in 1:25
        println(" φ($n) == $(φ(n))", is_prime(n) ? ", is prime" : "")
    end
    count = 0
    for n in 1:100_000
        count += is_prime(n)
        if n in [100, 1000, 10_000, 100_000]
            println("Primes up to $n: $count")
        end
    end
end

runphitests()
Output:

φ(1) == 1
φ(2) == 1, is prime
φ(3) == 2, is prime
φ(4) == 2
φ(5) == 4, is prime
φ(6) == 2
φ(7) == 6, is prime
φ(8) == 4
φ(9) == 6
φ(10) == 4
φ(11) == 10, is prime
φ(12) == 4
φ(13) == 12, is prime
φ(14) == 6
φ(15) == 8
φ(16) == 8
φ(17) == 16, is prime
φ(18) == 6
φ(19) == 18, is prime
φ(20) == 8
φ(21) == 12
φ(22) == 10
φ(23) == 22, is prime
φ(24) == 8
φ(25) == 20
Primes up to 100: 25
Primes up to 1000: 168
Primes up to 10000: 1229
Primes up to 100000: 9592

Kotlin

Translation of: Go
// Version 1.3.21

fun totient(n: Int): Int {
    var tot = n
    var nn = n
    var i = 2
    while (i * i <= nn) {
        if (nn % i == 0) {
            while (nn % i == 0) nn /= i
            tot -= tot / i
        }
        if (i == 2) i = 1
        i += 2
    }
    if (nn > 1) tot -= tot / nn
    return tot
}

fun main() {
    println(" n  phi   prime")
    println("---------------")
    var count = 0
    for (n in 1..25) {
        val tot = totient(n)
        val isPrime  = n - 1 == tot
        if (isPrime) count++
        System.out.printf("%2d   %2d   %b\n", n, tot, isPrime)
    }
    println("\nNumber of primes up to 25     = $count")
    for (n in 26..100_000) {
        val tot = totient(n)
        if (tot == n-1) count++
        if (n == 100 || n == 1000 || n % 10_000 == 0) {
            System.out.printf("\nNumber of primes up to %-6d = %d\n", n, count)
        }
    }
}
Output:
Same as Go example.

Lua

Averages about 7 seconds under LuaJIT

-- Return the greatest common denominator of x and y
function gcd (x, y)
  return y == 0 and math.abs(x) or gcd(y, x % y)
end

-- Return the totient number for n
function totient (n)
  local count = 0
  for k = 1, n do
    if gcd(n, k) == 1 then count = count + 1 end
  end
  return count
end

-- Determine (inefficiently) whether p is prime
function isPrime (p)
  return totient(p) == p - 1
end

-- Output totient and primality for the first 25 integers
print("n", string.char(237), "prime")
print(string.rep("-", 21))
for i = 1, 25 do
  print(i, totient(i), isPrime(i))
end

-- Count the primes up to 100, 1000 and 10000
local pCount, i, limit = 0, 1
for power = 2, 4 do
  limit = 10 ^ power
  repeat
    i = i + 1
    if isPrime(i) then pCount = pCount + 1 end
  until i == limit
  print("\nThere are " .. pCount .. " primes below " .. limit)
end
Output:
n       φ       prime
---------------------
1       1       false
2       1       true
3       2       true
4       2       false
5       4       true
6       2       false
7       6       true
8       4       false
9       6       false
10      4       false
11      10      true
12      4       false
13      12      true
14      6       false
15      8       false
16      8       false
17      16      true
18      6       false
19      18      true
20      8       false
21      12      false
22      10      false
23      22      true
24      8       false
25      20      false

There are 25 primes below 100

There are 168 primes below 1000

There are 1229 primes below 10000

Alternative, faster version - around 0.04 seconds using LuaJIT on TIO.RUN.

Translation of: ALGOL 68 – so using the totient algorithm from the second Go sample
do
    function totient( n ) -- returns the number of integers k where 1 <= k <= n that are mutually prime to n
        if     n <  3 then return 1
        elseif n == 3 then return 2
        else
           local result, v, i = n, n, 2
           while i * i <= v do
               if v % i == 0 then
                   while v % i == 0 do v = math.floor( v / i ) end
                   result = result - math.floor( result / i )
               end
               if i == 2 then
                   i = 1
               end
               i = i + 2
           end
           if v > 1 then result = result - math.floor( result / v ) end
           return result
       end
    end
    -- show the totient function values for the first 25 integers
    io.write( " n  phi(n) remarks\n" )
    for n = 1,25 do
        local tn = totient( n )
        io.write( string.format( "%2d", n ), ": ", string.format( "%5d", tn )
                , ( tn == n - 1 and tn ~= 0 and "  n is prime" or "" )
                , "\n"
                )
    end
    -- use the totient function to count primes
    local n100, n1000, n10000, n100000 = 0, 0, 0, 0
    for n = 1,100000 do
        if totient( n ) == n - 1 then
            if n <=    100 then    n100 = n100    + 1 end
            if n <=   1000 then   n1000 = n1000   + 1 end
            if n <=  10000 then  n10000 = n10000  + 1 end
            if n <= 100000 then n100000 = n100000 + 1 end
        end
    end
    io.write( "There are ", string.format( "%6d",    n100 ), " primes below      100\n" )
    io.write( "There are ", string.format( "%6d",   n1000 ), " primes below    1 000\n" )
    io.write( "There are ", string.format( "%6d",  n10000 ), " primes below   10 000\n" )
    io.write( "There are ", string.format( "%6d", n100000 ), " primes below  100 000\n" )
end
Output:
 n  phi(n) remarks
 1:     1
 2:     1  n is prime
 3:     2  n is prime
 4:     2
 5:     4  n is prime
 6:     2
 7:     6  n is prime
 8:     4
 9:     6
10:     4
11:    10  n is prime
12:     4
13:    12  n is prime
14:     6
15:     8
16:     8
17:    16  n is prime
18:     6
19:    18  n is prime
20:     8
21:    12
22:    10
23:    22  n is prime
24:     8
25:    20
There are     25 primes below      100
There are    168 primes below    1 000
There are   1229 primes below   10 000
There are   9592 primes below  100 000

MAD

Translation of: C
            NORMAL MODE IS INTEGER
            BOOLEAN PRM

            INTERNAL FUNCTION(A,B)
            ENTRY TO REM.
            FUNCTION RETURN A-A/B*B
            END OF FUNCTION

            INTERNAL FUNCTION(NN)
            ENTRY TO TOTENT.
            N = NN
            TOT = N
            THROUGH STEP, FOR I=2, 2, I*I.G.N
            WHENEVER REM.(N,I).E.0
                THROUGH DIV, FOR N=N, 0, REM.(N,I).NE.0
DIV             N = N/I
                TOT = TOT-TOT/I
            END OF CONDITIONAL
            WHENEVER I.E.2, I=1
STEP        CONTINUE
            WHENEVER N.G.1, TOT = TOT-TOT/N
            FUNCTION RETURN TOT
            END OF FUNCTION

            COUNT = 0
            PRINT FORMAT HEADER
            THROUGH FRST25, FOR KN=1, 1, KN.G.25
            KTOT = TOTENT.(KN)
            PRM = KTOT.E.KN-1
            WHENEVER PRM, COUNT = COUNT + 1
FRST25      PRINT FORMAT NUMTOT,KN,KTOT,PRM

            PRINT FORMAT NUMPRM,25,COUNT

            THROUGH CNTPRM, FOR KN=26, 1, KN.G.100000
            KTOT = TOTENT.(KN)
            WHENEVER KTOT.E.KN-1, COUNT = COUNT+1
            WHENEVER KN.E.100 .OR. KN.E.1000 .OR. REM.(KN,10000).E.0,
          0     PRINT FORMAT NUMPRM,KN,COUNT
CNTPRM      CONTINUE

            VECTOR VALUES HEADER = $19H  N  TOTIENT  PRIME*$
            VECTOR VALUES NUMTOT = $I2,S2,I7,S2,I5*$
            VECTOR VALUES NUMPRM = $22HNUMBER OF PRIMES UP TO,I7,1H:,I6*$
            END OF PROGRAM
Output:
 N  TOTIENT  PRIME
 1        1      0
 2        1      1
 3        2      1
 4        2      0
 5        4      1
 6        2      0
 7        6      1
 8        4      0
 9        6      0
10        4      0
11       10      1
12        4      0
13       12      1
14        6      0
15        8      0
16        8      0
17       16      1
18        6      0
19       18      1
20        8      0
21       12      0
22       10      0
23       22      1
24        8      0
25       20      0
NUMBER OF PRIMES UP TO     25:     9
NUMBER OF PRIMES UP TO    100:    25
NUMBER OF PRIMES UP TO   1000:   168
NUMBER OF PRIMES UP TO  10000:  1229
NUMBER OF PRIMES UP TO  20000:  2262
NUMBER OF PRIMES UP TO  30000:  3245
NUMBER OF PRIMES UP TO  40000:  4203
NUMBER OF PRIMES UP TO  50000:  5133
NUMBER OF PRIMES UP TO  60000:  6057
NUMBER OF PRIMES UP TO  70000:  6935
NUMBER OF PRIMES UP TO  80000:  7837
NUMBER OF PRIMES UP TO  90000:  8713
NUMBER OF PRIMES UP TO 100000:  9592

Mathematica / Wolfram Language

Do[
 tmp = EulerPhi[i];
 If[i - 1 == tmp,
  Print["\[CurlyPhi](", i, ")=", tmp, ", is prime"]
  ,
  Print["\[CurlyPhi](", i, ")=", tmp]
  ]
 ,
 {i, 25}
 ]
Count[EulerPhi[Range[100]] - Range[100], -1]
Count[EulerPhi[Range[1000]] - Range[1000], -1]
Count[EulerPhi[Range[10000]] - Range[10000], -1]
Count[EulerPhi[Range[100000]] - Range[100000], -1]
(*Alternative much faster way of findings the number primes up to a number*)
(*PrimePi[100]*)
(*PrimePi[1000]*)
(*PrimePi[10000]*)
(*PrimePi[100000]*)
Output:
φ(1)=1
φ(2)=1, is prime
φ(3)=2, is prime
φ(4)=2
φ(5)=4, is prime
φ(6)=2
φ(7)=6, is prime
φ(8)=4
φ(9)=6
φ(10)=4
φ(11)=10, is prime
φ(12)=4
φ(13)=12, is prime
φ(14)=6
φ(15)=8
φ(16)=8
φ(17)=16, is prime
φ(18)=6
φ(19)=18, is prime
φ(20)=8
φ(21)=12
φ(22)=10
φ(23)=22, is prime
φ(24)=8
φ(25)=20

25
168
1229
9592

Miranda

main :: [sys_message]
main = [Stdout (lay (map showline [1..25])),
        Stdout (lay (map countprimes (25:map (10^) [2..5])))]

countprimes :: num->[char]
countprimes n = "There are " ++ show amount ++ " primes up to " ++ show n
                where amount = #filter prime [2..n]

showline :: num->[char]
showline n = "phi(" ++ show n ++ ") = " ++ show (totient n) ++ ", " ++ kind
             where kind = "prime", if prime n
                        = "composite", otherwise

prime :: num->bool
prime n = totient n = n - 1

totient :: num->num
totient n = loop n n (2:[3, 5..])
            where loop tot n (d:ds)
                   = tot, if n<=1
                   = tot - tot div n, if d*d > n
                   = loop tot n ds, if n mod d ~= 0
                   = loop (tot - tot div d) (remfac n d) ds, otherwise
                  remfac n d = n, if n mod d ~= 0
                             = remfac (n div d) d, otherwise
Output:
phi(1) = 1, composite
phi(2) = 1, prime
phi(3) = 2, prime
phi(4) = 2, composite
phi(5) = 4, prime
phi(6) = 2, composite
phi(7) = 6, prime
phi(8) = 4, composite
phi(9) = 6, composite
phi(10) = 4, composite
phi(11) = 10, prime
phi(12) = 4, composite
phi(13) = 12, prime
phi(14) = 6, composite
phi(15) = 8, composite
phi(16) = 8, composite
phi(17) = 16, prime
phi(18) = 6, composite
phi(19) = 18, prime
phi(20) = 8, composite
phi(21) = 12, composite
phi(22) = 10, composite
phi(23) = 22, prime
phi(24) = 8, composite
phi(25) = 20, composite
There are 9 primes up to 25
There are 25 primes up to 100
There are 168 primes up to 1000
There are 1229 primes up to 10000
There are 9592 primes up to 100000

Modula-2

MODULE TotientFunction;
FROM InOut IMPORT WriteString, WriteCard, WriteLn;

VAR count, n, tot: CARDINAL;

PROCEDURE totient(n: CARDINAL): CARDINAL;
    VAR tot, i: CARDINAL;
BEGIN
    tot := n;
    i := 2;
    WHILE i*i <= n DO
        IF n MOD i = 0 THEN
            WHILE n MOD i = 0 DO
                n := n DIV i
            END;
            DEC(tot, tot DIV i)
        END;
        IF i=2 THEN i := 1 END;
        INC(i, 2)
    END;
    IF n>1 THEN
        DEC(tot, tot DIV n)
    END;
    RETURN tot
END totient;

PROCEDURE ShowPrimeCount(n, count: CARDINAL);
BEGIN
    WriteString("Number of primes up to");
    WriteCard(n, 6);
    WriteString(": ");
    WriteCard(count, 4);
    WriteLn
END ShowPrimeCount;

BEGIN
    count := 0;

    WriteString(" N  Totient  Prime");
    WriteLn;
    FOR n := 1 TO 25 DO
        tot := totient(n);
        WriteCard(n, 2);
        WriteCard(tot, 9);
        IF tot = n-1 THEN
            WriteString("    Yes");
            INC(count)
        ELSE
            WriteString("     No")
        END;
        WriteLn
    END;

    ShowPrimeCount(25, count);

    FOR n := 26 TO 10000 DO
        IF totient(n) = n-1 THEN INC(count) END;
        IF (n=100) OR (n=1000) OR (n=10000) THEN
            ShowPrimeCount(n, count)
        END;
    END
END TotientFunction.
Output:
 N  Totient  Prime
 1        1     No
 2        1    Yes
 3        2    Yes
 4        2     No
 5        4    Yes
 6        2     No
 7        6    Yes
 8        4     No
 9        6     No
10        4     No
11       10    Yes
12        4     No
13       12    Yes
14        6     No
15        8     No
16        8     No
17       16    Yes
18        6     No
19       18    Yes
20        8     No
21       12     No
22       10     No
23       22    Yes
24        8     No
25       20     No
Number of primes up to    25:    9
Number of primes up to   100:   25
Number of primes up to  1000:  168
Number of primes up to 10000: 1229

Nim

import strformat

func totient(n: int): int =
    var tot = n
    var nn = n
    var i = 2
    while i * i <= nn:
        if nn mod i == 0:
            while nn mod i == 0:
                nn = nn div i
            dec tot, tot div i
        if i == 2:
            i = 1
        inc i, 2
    if nn > 1:
        dec tot, tot div nn
    tot

echo " n    φ   prime"
echo "---------------"
var count = 0
for n in 1..25:
    let tot = totient(n)
    let isPrime = n - 1 == tot
    if isPrime:
        inc count
    echo fmt"{n:2}   {tot:2}   {isPrime}"
echo ""
echo fmt"Number of primes up to {25:>6} = {count:>4}"
for n in 26..100_000:
    let tot = totient(n)
    if tot == n - 1:
        inc count
    if n == 100 or n == 1000 or n mod 10_000 == 0:
        echo fmt"Number of primes up to {n:>6} = {count:>4}"
Output:
 n    φ   prime
---------------
 1    1   false
 2    1   true
 3    2   true
 4    2   false
 5    4   true
 6    2   false
 7    6   true
 8    4   false
 9    6   false
10    4   false
11   10   true
12    4   false
13   12   true
14    6   false
15    8   false
16    8   false
17   16   true
18    6   false
19   18   true
20    8   false
21   12   false
22   10   false
23   22   true
24    8   false
25   20   false

Number of primes up to     25 =    9
Number of primes up to    100 =   25
Number of primes up to   1000 =  168
Number of primes up to  10000 = 1229
Number of primes up to  20000 = 2262
Number of primes up to  30000 = 3245
Number of primes up to  40000 = 4203
Number of primes up to  50000 = 5133
Number of primes up to  60000 = 6057
Number of primes up to  70000 = 6935
Number of primes up to  80000 = 7837
Number of primes up to  90000 = 8713
Number of primes up to 100000 = 9592

Pascal

Yes, a very slow possibility to check prime

{$IFDEF FPC}
  {$MODE DELPHI}
{$IFEND}
function gcd_mod(u, v: NativeUint): NativeUint;inline;
//prerequisites  u > v and u,v > 0
  var
    t: NativeUInt;
  begin
    repeat
      t := u;
      u := v;
      v := t mod v;
    until v = 0;
    gcd_mod := u;
  end;

function Totient(n:NativeUint):NativeUint;
var
  i : NativeUint;
Begin
  result := 1;
  For i := 2 to n do
    inc(result,ORD(GCD_mod(n,i)=1));
end;

function CheckPrimeTotient(n:NativeUint):Boolean;inline;
begin
  result :=  (Totient(n) = (n-1));
end;

procedure OutCountPrimes(n:NativeUInt);
var
  i,cnt :  NativeUint;
begin
  cnt := 0;
  For i := 1 to n do
    inc(cnt,Ord(CheckPrimeTotient(i)));
  writeln(n:10,cnt:8);
end;

procedure display(n:NativeUint);
var
  idx,phi : NativeUint;
Begin
  if n = 0 then
    EXIT;
  writeln('number n':5,'Totient(n)':11,'isprime':8);
  For idx := 1 to n do
  Begin
    phi := Totient(idx);
    writeln(idx:4,phi:10,(phi=(idx-1)):12);
  end
end;
var
  i : NativeUint;
Begin
  display(25);

  writeln('Limit  primecount');
  i := 100;
  repeat
    OutCountPrimes(i);
    i := i*10;
  until i >100000;
end.
Output
number n Totient(n) isprime
   1         1       FALSE
   2         1        TRUE
   3         2        TRUE
   4         2       FALSE
   5         4        TRUE
   6         2       FALSE
   7         6        TRUE
   8         4       FALSE
   9         6       FALSE
  10         4       FALSE
  11        10        TRUE
  12         4       FALSE
  13        12        TRUE
  14         6       FALSE
  15         8       FALSE
  16         8       FALSE
  17        16        TRUE
  18         6       FALSE
  19        18        TRUE
  20         8       FALSE
  21        12       FALSE
  22        10       FALSE
  23        22        TRUE
  24         8       FALSE
  25        20       FALSE
Limit  primecount
       100      25
      1000     168
     10000    1229
    100000    9592

real  3m39,745s

alternative

changing Totient-funtion in program atop to Computing Euler's totient function on wikipedia, like GO and C.

Impressive speedup.Checking with only primes would be even faster.

function totient(n:NativeUInt):NativeUInt;
const
  //delta of numbers not divisible by 2,3,5 (0_1+6->7+4->11 ..+6->29+2->3_1
  delta : array[0..7] of NativeUint = (6,4,2,4,2,4,6,2);
var
  i, quot,idx: NativeUint;
Begin
  // div mod by constant is fast.
  //i = 2
  result := n;
  if (2*2 <= n) then
  Begin
    IF not(ODD(n)) then
    Begin
      // remove numbers with factor 2,4,8,16, ...
      while not(ODD(n)) do
        n := n DIV 2;
      //remove count of multiples of 2
      dec(result,result DIV 2);
    end;
  end;
  //i = 3
  If (3*3 <= n) AND (n mod 3 = 0) then
  Begin
    repeat
      quot := n DIV 3;
      IF n <> quot*3 then
        BREAK
      else
        n := quot;
    until false;
    dec(result,result DIV 3);
  end;
  //i = 5
  If (5*5 <= n) AND (n mod 5 = 0) then
  Begin
    repeat
      quot := n DIV 5;
      IF n <> quot*5 then
        BREAK
      else
        n := quot;
    until false;
    dec(result,result DIV 5);
  end;
  i := 7;
  idx := 1;
  //i = 7,11,13,17,19,23,29, ...49 ..
  while i*i <= n do
  Begin
    quot := n DIV i;
    if n = quot*i then
    Begin
      repeat
        IF n <> quot*i then
          BREAK
        else
          n := quot;
        quot := n DIV i;
      until false;
      dec(result,result DIV i);
    end;
    i := i + delta[idx];
    idx := (idx+1) AND 7;
  end;
  if n> 1 then
    dec(result,result div n);
end;
Output
number n Totient(n) isprime
   1         1       FALSE
   2         1        TRUE
   3         2        TRUE
   4         2       FALSE
   5         4        TRUE
   6         2       FALSE
   7         6        TRUE
   8         4       FALSE
   9         6       FALSE
  10         4       FALSE
  11        10        TRUE
  12         4       FALSE
  13        12        TRUE
  14         6       FALSE
  15         8       FALSE
  16         8       FALSE
  17        16        TRUE
  18         6       FALSE
  19        18        TRUE
  20         8       FALSE
  21        12       FALSE
  22        10       FALSE
  23        22        TRUE
  24         8       FALSE
  25        20       FALSE
Limit  primecount
       100      25
      1000     168
     10000    1229
    100000    9592
   1000000   78498
  10000000  664579

real	0m7,369s

Perl

Direct calculation of 𝜑

Translation of: Raku
use utf8;
binmode STDOUT, ":utf8";

sub gcd {
  my ($u, $v) = @_;
  while ($v) {
    ($u, $v) = ($v, $u % $v);
  }
  return abs($u);
}

push @𝜑, 0;
for $t (1..10000) {
    push @𝜑, scalar grep { 1 == gcd($_,$t) } 1..$t;
}

printf "𝜑(%2d) = %3d%s\n", $_, $𝜑[$_], $_ - $𝜑[$_] - 1 ? '' : ' Prime' for 1 .. 25;
print "\n";

for $limit (100, 1000, 10000) {
    printf "Count of primes <= $limit: %d\n", scalar grep {$_ == $𝜑[$_] + 1} 0..$limit;
}
Output:
𝜑( 1) =   1
𝜑( 2) =   1 Prime
𝜑( 3) =   2 Prime
𝜑( 4) =   2
𝜑( 5) =   4 Prime
𝜑( 6) =   2
𝜑( 7) =   6 Prime
𝜑( 8) =   4
𝜑( 9) =   6
𝜑(10) =   4
𝜑(11) =  10 Prime
𝜑(12) =   4
𝜑(13) =  12 Prime
𝜑(14) =   6
𝜑(15) =   8
𝜑(16) =   8
𝜑(17) =  16 Prime
𝜑(18) =   6
𝜑(19) =  18 Prime
𝜑(20) =   8
𝜑(21) =  12
𝜑(22) =  10
𝜑(23) =  22 Prime
𝜑(24) =   8
𝜑(25) =  20

Count of primes <= 100: 25
Count of primes <= 1000: 168
Count of primes <= 10000: 1229

Using 'ntheory' library

Much faster. Output is the same as above.

Library: ntheory
use utf8;
binmode STDOUT, ":utf8";

use ntheory qw(euler_phi);

my @𝜑 = euler_phi(0,10000);  # Returns list of all values in range

printf "𝜑(%2d) = %3d%s\n", $_, $𝜑[$_], $_ - $𝜑[$_] - 1 ? '' : ' Prime' for 1 .. 25;
print "\n";

for $limit (100, 1000, 10000) {
    printf "Count of primes <= $limit: %d\n", scalar grep {$_ == $𝜑[$_] + 1} 0..$limit;
}

Phix

Translation of: Go

As of 1.0.2 there is a builtin phi().

function totient(integer n)
    integer tot = n, i = 2
    while i*i<=n do
        if mod(n,i)=0 then
            while true do
                n /= i
                if mod(n,i)!=0 then exit end if
            end while
            tot -= tot/i
        end if
        i += iff(i=2?1:2)
    end while
    if n>1 then
        tot -= tot/n
    end if
    return tot
end function
 
printf(1," n  phi   prime\n")
printf(1," --------------\n")
integer count = 0
for n=1 to 25 do
    integer tot = totient(n),
            prime = (n-1=tot)
    count += prime
    string isp = iff(prime?"true":"false")
    printf(1,"%2d   %2d   %s\n",{n,tot,isp})
end for
printf(1,"\nNumber of primes up to 25     = %d\n",count)
for n=26 to 100000 do
    count += (totient(n)=n-1)
    if find(n,{100,1000,10000,100000}) then
        printf(1,"Number of primes up to %-6d = %d\n",{n,count})
    end if
end for
Output:
 n  phi   prime
 --------------
 1    1   false
 2    1   true
 3    2   true
 4    2   false
 5    4   true
 6    2   false
 7    6   true
 8    4   false
 9    6   false
10    4   false
11   10   true
12    4   false
13   12   true
14    6   false
15    8   false
16    8   false
17   16   true
18    6   false
19   18   true
20    8   false
21   12   false
22   10   false
23   22   true
24    8   false
25   20   false

Number of primes up to 25     = 9
Number of primes up to 100    = 25
Number of primes up to 1000   = 168
Number of primes up to 10000  = 1229
Number of primes up to 100000 = 9592

PL/I

Translation of: C
totientFunction: procedure options(main);
    totient: procedure(nn) returns(fixed);
        declare (nn, n, i, tot) fixed;
        n = nn;
        tot = n;
        do i=2 repeat(i+2) while(i*i <= n);
            if mod(n,i) = 0 then do;
                do while(mod(n,i) = 0);
                    n = n / i;
                end;
                tot = tot - tot / i;
            end;
            if i=2 then i=1;
        end;
        if n>1 then tot = tot - tot/n;
        return(tot);
    end totient;

    showPrimeCount: procedure(n, primeCount);
        declare (n, primeCount) fixed;
        put skip edit('There are', primeCount, ' primes up to', n) (A,F(5),A,F(6));
    end showPrimeCount;

    declare (n, primeCount, tot) fixed;
    do n = 1 to 25;
        tot = totient(n);
        put edit('phi(', n, ') = ', tot) (A,F(2),A,F(2));
        if tot = n-1 then do;
            put list('; prime');
            primeCount = primeCount + 1;
        end;
        put skip;
    end;

    call showPrimeCount(25, primeCount);
    do n = 26 to 10000;
        if totient(n) = n-1 then primeCount = primeCount + 1;
        if n=100 | n=1000 | n=10000 then
            call showPrimeCount(n, primeCount);
    end;
end totientFunction;
Output:
phi( 1) =  1
phi( 2) =  1 ; prime
phi( 3) =  2 ; prime
phi( 4) =  2
phi( 5) =  4 ; prime
phi( 6) =  2
phi( 7) =  6 ; prime
phi( 8) =  4
phi( 9) =  6
phi(10) =  4
phi(11) = 10 ; prime
phi(12) =  4
phi(13) = 12 ; prime
phi(14) =  6
phi(15) =  8
phi(16) =  8
phi(17) = 16 ; prime
phi(18) =  6
phi(19) = 18 ; prime
phi(20) =  8
phi(21) = 12
phi(22) = 10
phi(23) = 22 ; prime
phi(24) =  8
phi(25) = 20

There are    9 primes up to    25
There are   25 primes up to   100
There are  168 primes up to  1000
There are 1229 primes up to 10000

PL/M

Translation of: C
100H:
BDOS: PROCEDURE (F,A); DECLARE F BYTE, A ADDRESS; GO TO 5; END BDOS;
EXIT: PROCEDURE; GO TO 0; END EXIT;
PRINT: PROCEDURE (S); DECLARE S ADDRESS; CALL BDOS(9,S); END PRINT;

PRINT$NUM: PROCEDURE (N);
    DECLARE (N, P) ADDRESS, CH BASED P BYTE;
    DECLARE S (6) BYTE INITIAL ('.....$');
    P = .S(5);
DIGIT:
    P = P-1;
    CH = '0' + N MOD 10;
    IF (N := N/10) > 0 THEN GO TO DIGIT;
    CALL PRINT(P);
END PRINT$NUM;

TOTIENT: PROCEDURE (N) ADDRESS;
    DECLARE (TOT, N, I) ADDRESS;
    TOT = N;
    I = 2;
    DO WHILE I*I <= N;
        IF N MOD I = 0 THEN DO;
            DO WHILE (N := N / I) MOD I = 0; END;
            TOT = TOT - TOT / I;
        END;
        IF I=2 THEN I=1;
        I = I+2;
    END;
    IF N > 1 THEN TOT = TOT - TOT / N;
    RETURN TOT;
END TOTIENT;

SHOW$PRIME$COUNT: PROCEDURE (N, COUNT);
    DECLARE (N, COUNT) ADDRESS;
    CALL PRINT(.'THERE ARE $');
    CALL PRINT$NUM(COUNT);
    CALL PRINT(.' PRIMES UP TO $');
    CALL PRINT$NUM(N);
    CALL PRINT(.(13,10,'$'));
END SHOW$PRIME$COUNT;

DECLARE (N, TOT) ADDRESS;
DECLARE PRIME$COUNT ADDRESS INITIAL (0);

DO N = 1 TO 25;
    CALL PRINT(.'PHI($');
    CALL PRINT$NUM(N);
    CALL PRINT(.') = $');
    CALL PRINT$NUM(TOT := TOTIENT(N));
    IF TOT = N-1 THEN DO;
        CALL PRINT(.'; PRIME$');
        PRIME$COUNT = PRIME$COUNT + 1;
    END;
    CALL PRINT(.(13,10,'$'));
END;

CALL SHOW$PRIME$COUNT(25, PRIME$COUNT);
DO N = 26 TO 10000;
    IF TOTIENT(N) = N-1 THEN
        PRIME$COUNT = PRIME$COUNT + 1;
    IF N=100 OR N=1000 OR N=10000 THEN
        CALL SHOW$PRIME$COUNT(N, PRIME$COUNT);
END;

CALL EXIT;
EOF
Output:
PHI(1) = 1
PHI(2) = 1; PRIME
PHI(3) = 2; PRIME
PHI(4) = 2
PHI(5) = 4; PRIME
PHI(6) = 2
PHI(7) = 6; PRIME
PHI(8) = 4
PHI(9) = 6
PHI(10) = 4
PHI(11) = 10; PRIME
PHI(12) = 4
PHI(13) = 12; PRIME
PHI(14) = 6
PHI(15) = 8
PHI(16) = 8
PHI(17) = 16; PRIME
PHI(18) = 6
PHI(19) = 18; PRIME
PHI(20) = 8
PHI(21) = 12
PHI(22) = 10
PHI(23) = 22; PRIME
PHI(24) = 8
PHI(25) = 20
THERE ARE 9 PRIMES UP TO 25
THERE ARE 25 PRIMES UP TO 100
THERE ARE 168 PRIMES UP TO 1000
THERE ARE 1229 PRIMES UP TO 10000

PicoLisp

(gc 32)
(de gcd (A B)
   (until (=0 B)
      (let M (% A B)
         (setq A B B M) ) )
   (abs A) )
(de totient (N)
   (let C 0
      (for I N
         (and (=1 (gcd N I)) (inc 'C)) )
      (cons C (= C (dec N))) ) )
(de p? (N)
   (let C 0
      (for A N
         (and
            (cdr (totient A))
            (inc 'C) ) )
      C ) )
(let Fmt (3 7 10)
   (tab Fmt "N" "Phi" "Prime?")
   (tab Fmt "-" "---" "------")
   (for N 25
      (tab Fmt
         N
         (car (setq @ (totient N)))
         (cdr @) ) ) )
(println
   (mapcar p? (25 100 1000 10000 100000)) )
Output:
 
  N    Phi    Prime?
  -    ---    ------
  1      1
  2      1         T
  3      2         T
  4      2
  5      4         T
  6      2
  7      6         T
  8      4
  9      6
 10      4
 11     10         T
 12      4
 13     12         T
 14      6
 15      8
 16      8
 17     16         T
 18      6
 19     18         T
 20      8
 21     12
 22     10
 23     22         T
 24      8
 25     20
(9 25 168 1229 9592)

Python

from math import gcd

def  φ(n):
    return sum(1 for k in range(1, n + 1) if gcd(n, k) == 1)

if __name__ == '__main__':
    def is_prime(n):
        return φ(n) == n - 1
    
    for n in range(1, 26):
        print(f" φ({n}) == {φ(n)}{', is prime' if is_prime(n)  else ''}")
    count = 0
    for n in range(1, 10_000 + 1):
        count += is_prime(n)
        if n in {100, 1000, 10_000}:
            print(f"Primes up to {n}: {count}")
Output:
 φ(1) == 1
 φ(2) == 1, is prime
 φ(3) == 2, is prime
 φ(4) == 2
 φ(5) == 4, is prime
 φ(6) == 2
 φ(7) == 6, is prime
 φ(8) == 4
 φ(9) == 6
 φ(10) == 4
 φ(11) == 10, is prime
 φ(12) == 4
 φ(13) == 12, is prime
 φ(14) == 6
 φ(15) == 8
 φ(16) == 8
 φ(17) == 16, is prime
 φ(18) == 6
 φ(19) == 18, is prime
 φ(20) == 8
 φ(21) == 12
 φ(22) == 10
 φ(23) == 22, is prime
 φ(24) == 8
 φ(25) == 20
Primes up to 100: 25
Primes up to 1000: 168
Primes up to 10000: 1229

Quackery

gcd is defined at Greatest common divisor#Quackery.

  [ 0 swap dup times 
      [ i over gcd 
        1 = rot + swap ] 
      drop ]                is totient    (   n --> n )
     
  [ 0 temp put
    times
      [ i dup 1+ totient
        = temp tally ]
     temp take ]            is primecount (   n --> n )

  25 times
     [ say "The totient of "
       i^ 1+ dup echo
       say " is "
       dup totient dup echo
       say ", so it is "
       1+ != if say "not "
       say "prime." cr ] 
  cr
  ' [ 100 1000 10000 100000 ] 
  witheach 
    [ say "There are "
      dup primecount echo 
      say " primes up to " echo
      say "." cr ]

((Out}}

The totient of 1 is 1, so it is not prime.
The totient of 2 is 1, so it is prime.
The totient of 3 is 2, so it is prime.
The totient of 4 is 2, so it is not prime.
The totient of 5 is 4, so it is prime.
The totient of 6 is 2, so it is not prime.
The totient of 7 is 6, so it is prime.
The totient of 8 is 4, so it is not prime.
The totient of 9 is 6, so it is not prime.
The totient of 10 is 4, so it is not prime.
The totient of 11 is 10, so it is prime.
The totient of 12 is 4, so it is not prime.
The totient of 13 is 12, so it is prime.
The totient of 14 is 6, so it is not prime.
The totient of 15 is 8, so it is not prime.
The totient of 16 is 8, so it is not prime.
The totient of 17 is 16, so it is prime.
The totient of 18 is 6, so it is not prime.
The totient of 19 is 18, so it is prime.
The totient of 20 is 8, so it is not prime.
The totient of 21 is 12, so it is not prime.
The totient of 22 is 10, so it is not prime.
The totient of 23 is 22, so it is prime.
The totient of 24 is 8, so it is not prime.
The totient of 25 is 20, so it is not prime.

There are 25 primes up to 100.
There are 168 primes up to 1000.
There are 1229 primes up to 10000.
There are 9592 primes up to 100000.

Racket

#lang racket
 
(require math/number-theory)
 
(define (prime*? n) (= (totient n) (sub1 n)))
 
(for ([n (in-range 1 26)])
  (printf "φ(~a) = ~a~a~a\n"
          n
          (totient n)
          (if (prime*? n) " is prime" "")
          (if (prime? n) " (confirmed)" "")))
 
(for/fold ([count 0] #:result (void)) ([n (in-range 1 10001)])
   (define new-count (if (prime*? n) (add1 count) count))
   (when (member n '(100 1000 10000))
     (printf "Primes up to ~a: ~a\n" n new-count))
   new-count)
Output:
φ(1) = 1
φ(2) = 1 is prime (confirmed)
φ(3) = 2 is prime (confirmed)
φ(4) = 2
φ(5) = 4 is prime (confirmed)
φ(6) = 2
φ(7) = 6 is prime (confirmed)
φ(8) = 4
φ(9) = 6
φ(10) = 4
φ(11) = 10 is prime (confirmed)
φ(12) = 4
φ(13) = 12 is prime (confirmed)
φ(14) = 6
φ(15) = 8
φ(16) = 8
φ(17) = 16 is prime (confirmed)
φ(18) = 6
φ(19) = 18 is prime (confirmed)
φ(20) = 8
φ(21) = 12
φ(22) = 10
φ(23) = 22 is prime (confirmed)
φ(24) = 8
φ(25) = 20
Primes up to 100: 25
Primes up to 1000: 168
Primes up to 10000: 1229

Raku

(formerly Perl 6)

Works with: Rakudo version 2018.11

This is an incredibly inefficient way of finding prime numbers.

use Prime::Factor;

my \𝜑 = 0, |(1..*).hyper.map: -> \t { t * [*] t.&prime-factors.squish.map: { 1 - 1/$_ } }

printf "𝜑(%2d) = %3d %s\n", $_, 𝜑[$_], $_ - 𝜑[$_] - 1 ?? '' !! 'Prime' for 1 .. 25;

(1e2, 1e3, 1e4, 1e5).map: -> $limit {
    say "\nCount of primes <= $limit: " ~ +(^$limit).grep: {$_ == 𝜑[$_] + 1}
}
Output:
𝜑( 1) =   1
𝜑( 2) =   1 Prime
𝜑( 3) =   2 Prime
𝜑( 4) =   2
𝜑( 5) =   4 Prime
𝜑( 6) =   2
𝜑( 7) =   6 Prime
𝜑( 8) =   4
𝜑( 9) =   6
𝜑(10) =   4
𝜑(11) =  10 Prime
𝜑(12) =   4
𝜑(13) =  12 Prime
𝜑(14) =   6
𝜑(15) =   8
𝜑(16) =   8
𝜑(17) =  16 Prime
𝜑(18) =   6
𝜑(19) =  18 Prime
𝜑(20) =   8
𝜑(21) =  12
𝜑(22) =  10
𝜑(23) =  22 Prime
𝜑(24) =   8
𝜑(25) =  20

Count of primes <= 100: 25

Count of primes <= 1000: 168

Count of primes <= 10000: 1229

Count of primes <= 100000: 9592

REXX

idiomatic

/*REXX program calculates the totient numbers for a range of numbers, and count primes. */
parse arg N .                                    /*obtain optional argument from the CL.*/
if N==''  |  N==","  then N= 25                  /*Not specified?  Then use the default.*/
tell= N>0                                        /*N positive>?  Then display them all. */
N= abs(N)                                        /*use the absolute value of N for loop.*/
w= length(N)                                     /*W:  is used in aligning the output.  */
primes= 0                                        /*the number of primes found  (so far).*/
                                                 /*if N was negative, only count primes.*/
    do j=1  for  N;              T= phi(j)       /*obtain totient number for a number.  */
    prime= word('(prime)', 1 +  (T \== j-1 ) )   /*determine if  J  is a prime number.  */
    if prime\==''  then primes= primes + 1       /*if a prime, then bump the prime count*/
    if tell  then say 'totient number for '  right(j, w)  " ──► "  right(T, w)  ' '  prime
    end   /*j*/
say
say right(primes, w)      ' primes detected for numbers up to and including '        N
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
gcd: parse arg x,y;   do until y==0;     parse value   x//y  y    with    y  x
                      end   /*until*/;                                            return x
/*──────────────────────────────────────────────────────────────────────────────────────*/
phi: procedure; parse arg z;             if z==1  then return 1
     #= 1
                      do m=2  for z-2;   if gcd(m, z)==1  then #= # + 1
                      end   /*m*/;                                                return #
output   when using the default input of:     25
totient number for   1  ──►   1
totient number for   2  ──►   1   (prime)
totient number for   3  ──►   2   (prime)
totient number for   4  ──►   2
totient number for   5  ──►   4   (prime)
totient number for   6  ──►   2
totient number for   7  ──►   6   (prime)
totient number for   8  ──►   4
totient number for   9  ──►   6
totient number for  10  ──►   4
totient number for  11  ──►  10   (prime)
totient number for  12  ──►   4
totient number for  13  ──►  12   (prime)
totient number for  14  ──►   6
totient number for  15  ──►   8
totient number for  16  ──►   8
totient number for  17  ──►  16   (prime)
totient number for  18  ──►   6
totient number for  19  ──►  18   (prime)
totient number for  20  ──►   8
totient number for  21  ──►  12
totient number for  22  ──►  10
totient number for  23  ──►  22   (prime)
totient number for  24  ──►   8
totient number for  25  ──►  20

 9  primes detected for numbers up to and including  25
output   when using the input of:     -100
 25  primes detected for numbers up to and including  100
output   when using the input of:     -1000
 168  primes detected for numbers up to and including  1000
output   when using the input of:     -10000
 1229  primes detected for numbers up to and including  10000
output   when using the input of:     -1000000
 9592 primes detected for numbers up to and including  100000

optimized

This REXX version moved the   gcd   function in-line.
It is about   7%   faster than the 1st version.

/*REXX program calculates the totient numbers for a range of numbers, and count primes. */
parse arg N .                                    /*obtain optional argument from the CL.*/
if N==''  |  N==","  then N= 25                  /*Not specified?  Then use the default.*/
tell= N>0                                        /*N positive>?  Then display them all. */
N= abs(N)                                        /*use the absolute value of N for loop.*/
w= length(N)                                     /*W:  is used in aligning the output.  */
primes= 0                                        /*the number of primes found  (so far).*/
                                                 /*if N was negative, only count primes.*/
    do j=1  for  N;              T= phi(j)       /*obtain totient number for a number.  */
    prime= word('(prime)', 1 +  (T \== j-1 ) )   /*determine if  J  is a prime number.  */
    if prime\==''  then primes= primes + 1       /*if a prime, then bump the prime count*/
    if tell  then say 'totient number for '  right(j, w)  " ──► "  right(T, w)  ' '  prime
    end   /*j*/
say
say right(primes, w)      ' primes detected for numbers up to and including '        N
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
phi: procedure; parse arg z;                       if z==1  then return 1
     #= 1
                            do m=2  for z-2;       parse value     m   z    with    x  y
                                do until y==0;     parse value   x//y  y    with    y  x
                                end   /*until*/
                            if x==1  then #= # + 1
                            end       /*m*/
     return #
output   is identical to the 1st REXX version.


RPL

GCD approach

Very compact code, but very slow algorithm.

≪ → n 
  ≪ 0 1 n FOR j 
       n j 
       WHILE DUP REPEAT SWAP OVER MOD END 
       DROP 1 == +
    NEXT 
≫ ≫ 
‘PHI’ STO

≪ 1 1 ROT FOR j 
     j DUP PHI - 1 == + 
  2 STEP 
≫
'CNTPR' STO
25 PHI
10000 CNTPR
Output:
2: 20
1: 1229

Faster version

Translation of: C

Calculator simulator's timedog unfortunately prevents from running the code to count up to 100,000.

Works with: Halcyon Calc version 4.2.7
≪ DUP 2 OVER √ 
  FOR j 
     IF DUP j MOD NOT THEN
        WHILE DUP j MOD NOT REPEAT 
           j / 
        END
        SWAP DUP j / - SWAP 
     END 
     IF j 2 == THEN 1 'j' STO END 
  2 STEP 
  IF DUP 1 > THEN OVER SWAP / - ELSE DROP END 
≫
‘PHI’ STO

Ruby

require "prime"

def 𝜑(n)
  n.prime_division.inject(1){|res, (pr, exp)| res * (pr-1) * pr**(exp-1) } 
end

1.upto 25 do |n|
  tot = 𝜑(n)
  puts "#{n}\t #{tot}\t #{"prime" if n-tot==1}"
end

[100, 1_000, 10_000, 100_000].each do |u|
  puts "Number of primes up to #{u}: #{(1..u).count{|n| n-𝜑(n) == 1} }"
end
Output:
1	 1	 
2	 1	 prime
3	 2	 prime
4	 2	 
5	 4	 prime
6	 2	 
7	 6	 prime
8	 4	 
9	 6	 
10	 4	 
11	 10	 prime
12	 4	 
13	 12	 prime
14	 6	 
15	 8	 
16	 8	 
17	 16	 prime
18	 6	 
19	 18	 prime
20	 8	 
21	 12	 
22	 10	 
23	 22	 prime
24	 8	 
25	 20	 
Number of primes up to 100: 25
Number of primes up to 1000: 168
Number of primes up to 10000: 1229
Number of primes up to 100000: 9592

Rust

use num::integer::gcd;

fn main() {
    // Compute the totient of the first 25 natural integers
    println!("N\t phi(n)\t Prime");
    for n in 1..26 {
        let phi_n = phi(n);
        println!("{}\t {}\t {:?}", n, phi_n, phi_n == n - 1);
    }

    // Compute the number of prime numbers for various steps
    [1, 100, 1000, 10000, 100000]
        .windows(2)
        .scan(0, |acc, tuple| {
            *acc += (tuple[0]..=tuple[1]).filter(is_prime).count();
            Some((tuple[1], *acc))
        })
        .for_each(|x| println!("Until {}: {} prime numbers", x.0, x.1));
}

fn is_prime(n: &usize) -> bool {
    phi(*n) == *n - 1
}

fn phi(n: usize) -> usize {
    (1..=n).filter(|&x| gcd(n, x) == 1).count()
}

Output is:

N	 phi(n)	 Prime
1	 1	 false
2	 1	 true
3	 2	 true
4	 2	 false
5	 4	 true
6	 2	 false
7	 6	 true
8	 4	 false
9	 6	 false
10	 4	 false
11	 10	 true
12	 4	 false
13	 12	 true
14	 6	 false
15	 8	 false
16	 8	 false
17	 16	 true
18	 6	 false
19	 18	 true
20	 8	 false
21	 12	 false
22	 10	 false
23	 22	 true
24	 8	 false
25	 20	 false
Until 100: 25 prime numbers
Until 1000: 168 prime numbers
Until 10000: 1229 prime numbers
Until 100000: 9592 prime numbers

S-BASIC

$lines

rem - return p mod q
function mod(p, q = integer) = integer
end = p - q * (p / q)

rem - return greatest common divisor of x and y
function gcd(x, y = integer) = integer
   var r, temp = integer
   if x < y then
      begin
         temp = x
         x = y
         y = temp
      end
   r = mod(x, y)
   while r <> 0 do
      begin
         x = y
         y = r
         r = mod(x, y)
      end
end = y

rem - return phi (also called totient) of n
function phi(n = integer) = integer
   var i, count = integer
   count = 1
   for i = 2 to n
      if gcd(n, i) = 1 then count = count + 1
   next i
end = count

rem - exercise the function
var n, totient, count = integer
print "  n    Phi(n)   Prime?"
for n = 1 to 25
   totient = phi(n)
   print using "####  ####     ";n, totient;
   if totient + 1 = n then
      print "yes"
   else
      print "no"
next n

rem - and further test it by counting primes
print
count = 0
for n = 1 to 1000
   if phi(n) = n - 1 then count = count + 1
   if n = 100 then
      print "Primes up to 100  = ";count
   else if n = 1000 then
      print "Primes up to 1000 = ";count
next n

end
Output:
  n    Phi(n) Prime?
   1     1     no
   2     1     yes
   3     2     yes
   4     2     no
   5     4     yes
   6     2     no
   7     6     yes
   8     4     no
   9     6     no
  10     4     no
  11    10     yes
  12     4     no
  13    12     yes
  14     6     no
  15     8     no
  16     8     no
  17    16     yes
  18     6     no
  19    18     yes
  20     8     no
  21    12     no
  22    10     no
  23    22     yes
  24     8     no
  25    20     no

Primes up to 100  =  25
Primes up to 1000 = 168

Scala

The most concise way to write the totient function in Scala is using a naive lazy list:

@tailrec
def gcd(a: Int, b: Int): Int = if(b == 0) a else gcd(b, a%b)
def totientLaz(num: Int): Int = LazyList.range(2, num).count(gcd(num, _) == 1) + 1

The above approach, while concise, is not very performant. It must check the GCD with every number between 2 and num, giving it an O(n*log(n)) time complexity. A better solution is to use the product definition of the totient, repeatedly extracting prime factors from num:

def totientPrd(num: Int): Int = {
  @tailrec
  def dTrec(f: Int, n: Int): Int = if(n%f == 0) dTrec(f, n/f) else n
  
  @tailrec
  def tTrec(ac: Int, i: Int, n: Int): Int = if(n != 1){
    if(n%i == 0) tTrec(ac*(i - 1)/i, i + 1, dTrec(i, n))
    else tTrec(ac, i + 1, n)
  }else{
    ac
  }
  
  tTrec(num, 2, num)
}

This version is significantly faster, but the introduction of multiple recursive methods makes it far less concise. We can, however, embed the recursion into a lazy list to obtain a function as fast as the second example yet almost as concise as the first, at the cost of some readability:

@tailrec
def scrub(f: Long, num: Long): Long = if(num%f == 0) scrub(f, num/f) else num
def totientLazPrd(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)}.find(_._3 == 1).get._1

To generate the output up to 100000, Longs are necessary.

Output:
1 (Not Prime): 1
2   (Prime)  : 1
3   (Prime)  : 2
4 (Not Prime): 2
5   (Prime)  : 4
6 (Not Prime): 2
7   (Prime)  : 6
8 (Not Prime): 4
9 (Not Prime): 6
10 (Not Prime): 4
11   (Prime)  : 10
12 (Not Prime): 4
13   (Prime)  : 12
14 (Not Prime): 6
15 (Not Prime): 8
16 (Not Prime): 8
17   (Prime)  : 16
18 (Not Prime): 6
19   (Prime)  : 18
20 (Not Prime): 8
21 (Not Prime): 12
22 (Not Prime): 10
23   (Prime)  : 22
24 (Not Prime): 8
25 (Not Prime): 20

Prime Count <= N...
100: 25
1000: 168
10000: 1229
100000: 9592

SETL

program totient;
    loop for n in [1..1000000] do
        tot := totient(n);
        if tot = n-1 then prime +:= 1; end if;

        if n <= 25 then
            print(lpad(str n, 2), "  ",
                  lpad(str tot, 2), "  ",
                  if tot = n-1 then "prime" else "" end if);
        end if;

        if n in [1000,10000,100000,1000000] then
            print(lpad(str prime,8), "primes up to" + lpad(str n,8));
        end if;
    end loop;

    proc totient(n);
        tot := n;
        i := 2;
        loop while i*i <= n do
            if n mod i = 0 then
                loop while n mod i = 0 do
                    n div:= i;
                end loop;
                tot -:= tot div i;
            end if;
            if i=2 then i:=3;
            else i+:=2;
            end if;
        end loop;
        if n>1 then
            tot -:= tot div n;
        end if;
        return tot;
    end proc;
end program;
Output:
 1     1
 2     1    prime
 3     2    prime
 4     2
 5     4    prime
 6     2
 7     6    prime
 8     4
 9     6
10     4
11    10    prime
12     4
13    12    prime
14     6
15     8
16     8
17    16    prime
18     6
19    18    prime
20     8
21    12
22    10
23    22    prime
24     8
25    20
     168 primes up to    1000
    1229 primes up to   10000
    9592 primes up to  100000
   78498 primes up to 1000000

Shale

#!/usr/local/bin/shale

primes library

init dup var {
  pl sieve type primes::()
  100000 0 pl generate primes::()
} =

go dup var {
  i var
  c0 var
  c1 var
  c2 var
  c3 var
  p var

  " N  Phi  Is prime" println
  i 1 =
  { i 25 <= } {
    i pl isprime primes::() { "True" } { "False" } if i pl phi primes::() i "%2d  %3d  %s\n" printf
    i++
  } while

  c0 0 =
  c1 0 =
  c2 0 =
  c3 0 =
  i 0 =
  { i count pl:: < } {
    p i pl get primes::() =
    p 100 < { c0++ } ifthen
    p 1000 < { c1++ } ifthen
    p 10000 < { c2 ++ } ifthen
    p 100000 < { c3 ++ } ifthen
    i++
  } while

  "" println
  "  Limit  Count" println
  c0 "    100  %5d\n" printf
  c1 "  1,000  %5d\n" printf
  c2 " 10,000  %5d\n" printf
  c3 "100,000  %5d\n" printf
} =

init()
go()
Output:
 N  Phi  Is prime
 1    1  False
 2    1  True
 3    2  True
 4    2  False
 5    4  True
 6    2  False
 7    6  True
 8    4  False
 9    6  False
10    4  False
11   10  True
12    4  False
13   12  True
14    6  False
15    8  False
16    8  False
17   16  True
18    6  False
19   18  True
20    8  False
21   12  False
22   10  False
23   22  True
24    8  False
25   20  False

  Limit  Count
    100     25
  1,000    168
 10,000   1229
100,000   9592

Sidef

The Euler totient function is built-in as Number.euler_phi(), but we can easily re-implement it using its multiplicative property: phi(p^k) = (p-1)*p^(k-1).

func 𝜑(n) {
    n.factor_exp.prod {|p|
        (p[0]-1) * p[0]**(p[1]-1)
    }
}
for n in (1..25) {
    var totient = 𝜑(n)
    printf("𝜑(%2s) = %3s%s\n", n, totient, totient==(n-1) ? ' - prime' : '')
}
Output:
𝜑( 1) =   1
𝜑( 2) =   1 - prime
𝜑( 3) =   2 - prime
𝜑( 4) =   2
𝜑( 5) =   4 - prime
𝜑( 6) =   2
𝜑( 7) =   6 - prime
𝜑( 8) =   4
𝜑( 9) =   6
𝜑(10) =   4
𝜑(11) =  10 - prime
𝜑(12) =   4
𝜑(13) =  12 - prime
𝜑(14) =   6
𝜑(15) =   8
𝜑(16) =   8
𝜑(17) =  16 - prime
𝜑(18) =   6
𝜑(19) =  18 - prime
𝜑(20) =   8
𝜑(21) =  12
𝜑(22) =  10
𝜑(23) =  22 - prime
𝜑(24) =   8
𝜑(25) =  20
[100, 1_000, 10_000, 100_000].each {|limit|
    var pi = (1..limit -> count_by {|n| 𝜑(n) == (n-1) })
    say "Number of primes <= #{limit}: #{pi}"
}
Output:
Number of primes <= 100: 25
Number of primes <= 1000: 168
Number of primes <= 10000: 1229
Number of primes <= 100000: 9592

Tiny BASIC

1 indicates prime, 0 indicates not prime.

     REM PRINT THE DATA FOR N=1 TO 25
     LET N = 0
  10 LET N = N + 1
     IF N = 26 THEN GOTO 100
     GOSUB 1000
     IF T = N - 1 THEN LET P = 1
     IF T <> N - 1 THEN LET P = 0
     PRINT N," ", T," ",P
     GOTO 10
 100 REM COUNT PRIMES BELOW 10000
     LET C = 0
     LET N = 2
 110 GOSUB 1000
     IF T = N - 1 THEN LET C = C + 1
     IF N = 100 THEN PRINT "There are ", C, " primes below 100."
     IF N = 1000 THEN PRINT "There are ", C, " primes below 1000."
     IF N = 10000 THEN PRINT "There are ", C, " primes below 10000."
     LET N = N + 1
     IF N < 10001 THEN GOTO 110
     END
1000 REM TOTIENT FUNCTION OF INTEGER N
     LET M = 1
     LET T = 0
1010 IF M > N THEN RETURN
     LET A = N
     LET B = M    REM NEED TO RENAME THESE SO THEY ARE PRESERVED
     GOSUB 2000
     IF G = 1 THEN LET T = T + 1
     LET M = M + 1
     GOTO 1010
2000 REM GCD OF INTEGERS A, B
2010 IF A>B THEN GOTO 2020
     LET B = B - A
     IF A=0 THEN LET G = B
     IF A=0 THEN RETURN
2020 LET S = A
     LET A = B
     LET B = S
     GOTO 2010
Output:
1 1 0

2 1 1 3 2 1 4 2 0 5 4 1 6 2 0 7 6 1 8 4 0 9 6 0 10 4 0 11 10 1 12 4 0 13 12 1 14 6 0 15 8 0 16 8 0 17 16 1 18 6 0 19 18 1 20 8 0 21 12 0 22 10 0 23 22 1 24 8 0 25 20 0 There are 25 primes below 100. There are 168 primes below 1000.

There are 1229 primes below 10000.

VBA

Translation of: Phix
Private Function totient(ByVal n As Long) As Long
    Dim tot As Long: tot = n
    Dim i As Long: i = 2
    Do While i * i <= n
        If n Mod i = 0 Then
            Do While True
                n = n \ i
                If n Mod i <> 0 Then Exit Do
            Loop
            tot = tot - tot \ i
        End If
        i = i + IIf(i = 2, 1, 2)
    Loop
    If n > 1 Then
        tot = tot - tot \ n
    End If
    totient = tot
End Function

Public Sub main()
    Debug.Print " n  phi   prime"
    Debug.Print " --------------"
    Dim count As Long
    Dim tot As Integer, n As Long
    For n = 1 To 25
        tot = totient(n)
        prime = (n - 1 = tot)
        count = count - prime
        Debug.Print Format(n, "@@"); Format(tot, "@@@@@"); Format(prime, "@@@@@@@@")
    Next n
    Debug.Print
    Debug.Print "Number of primes up to 25     = "; Format(count, "@@@@")
    For n = 26 To 100000
        count = count - (totient(n) = n - 1)
        Select Case n
            Case 100, 1000, 10000, 100000
                Debug.Print "Number of primes up to"; n; String$(6 - Len(CStr(n)), " "); "="; Format(count, "@@@@@")
            Case Else
        End Select
    Next n
End Sub
Output:
 n  phi   prime
 --------------
 1    1   False
 2    1    True
 3    2    True
 4    2   False
 5    4    True
 6    2   False
 7    6    True
 8    4   False
 9    6   False
10    4   False
11   10    True
12    4   False
13   12    True
14    6   False
15    8   False
16    8   False
17   16    True
18    6   False
19   18    True
20    8   False
21   12   False
22   10   False
23   22    True
24    8   False
25   20   False

Number of primes up to 25     =    9
Number of primes up to 100    =   25
Number of primes up to 1000   =  168
Number of primes up to 10000  = 1229
Number of primes up to 100000 = 9592

Visual Basic .NET

Translation of: C#
Imports System.Linq.Enumerable

Module Module1

    Sub Main()
        For i = 1 To 25
            Dim t = Totient(i)
            Console.WriteLine("{0}{1}{2}{3}", i, vbTab, t, If(t = i - 1, vbTab & "prime", ""))
        Next
        Console.WriteLine()

        Dim j = 100
        While j <= 100000
            Console.WriteLine($"{Range(1, j).Count(Function(x) Totient(x) + 1 = x):n0} primes below {j:n0}")
            j *= 10
        End While
    End Sub

    Function Totient(n As Integer) As Integer
        If n < 3 Then
            Return 1
        End If
        If n = 3 Then
            Return 2
        End If

        Dim tot = n

        If (n And 1) = 0 Then
            tot >>= 1
            Do
                n >>= 1
            Loop While (n And 1) = 0
        End If

        Dim i = 3
        While i * i <= n
            If n Mod i = 0 Then
                tot -= tot \ i
                Do
                    n \= i
                Loop While (n Mod i) = 0
            End If
            i += 2
        End While

        If n > 1 Then
            tot -= tot \ n
        End If

        Return tot
    End Function

End Module
Output:
1       1
2       1       prime
3       2       prime
4       2
5       4       prime
6       2
7       6       prime
8       4
9       6
10      4
11      10      prime
12      4
13      12      prime
14      6
15      8
16      8
17      16      prime
18      6
19      18      prime
20      8
21      12
22      10
23      22      prime
24      8
25      20

25 primes below 100
168 primes below 1,000
1,229 primes below 10,000
9,592 primes below 100,000

Wren

Translation of: Go
Library: Wren-fmt
import "./fmt" for Fmt

var totient = Fn.new { |n|
    var tot = n
    var i = 2
    while (i*i <= n) {
        if (n%i == 0) {
            while(n%i == 0) n = (n/i).floor
            tot = tot - (tot/i).floor
        }
        if (i == 2) i = 1
        i = i + 2
    }
    if (n > 1) tot = tot - (tot/n).floor
    return tot
}

System.print(" n  phi   prime")
System.print("---------------")
var count = 0
for (n in 1..25) {
    var tot = totient.call(n)
    var isPrime = (n - 1) == tot
    if (isPrime) count = count + 1
    System.print("%(Fmt.d(2, n))   %(Fmt.d(2, tot))   %(isPrime)")
}
System.print("\nNumber of primes up to 25     = %(count)")
for (n in 26..100000) {
    var tot = totient.call(n)
    if (tot == n - 1) count = count + 1
    if (n == 100 || n == 1000 || n%10000 == 0) {
        System.print("\nNumber of primes up to %(Fmt.d(-6, n)) = %(count)")
    }
}
Output:
 n  phi   prime
---------------
 1    1   false
 2    1   true
 3    2   true
 4    2   false
 5    4   true
 6    2   false
 7    6   true
 8    4   false
 9    6   false
10    4   false
11   10   true
12    4   false
13   12   true
14    6   false
15    8   false
16    8   false
17   16   true
18    6   false
19   18   true
20    8   false
21   12   false
22   10   false
23   22   true
24    8   false
25   20   false

Number of primes up to 25     = 9

Number of primes up to 100    = 25

Number of primes up to 1000   = 168

Number of primes up to 10000  = 1229

Number of primes up to 20000  = 2262

Number of primes up to 30000  = 3245

Number of primes up to 40000  = 4203

Number of primes up to 50000  = 5133

Number of primes up to 60000  = 6057

Number of primes up to 70000  = 6935

Number of primes up to 80000  = 7837

Number of primes up to 90000  = 8713

Number of primes up to 100000 = 9592

XPL0

func GCD(N, D);         \Return the greatest common divisor of N and D
int  N, D;              \numerator and denominator
int  R;
[if D > N then
    [R:= D;  D:= N;  N:= R];    \swap D and N
while D > 0 do
    [R:= rem(N/D);
    N:= D;
    D:= R;
    ];
return N;
];      \GCD

func Totient(N);        \Return the totient of N
int  N, Phi, M;
[Phi:= 0;
for M:= 1 to N do
    if GCD(M, N) = 1 then Phi:= Phi+1;
return Phi;
];

int N, Phi, Pwr, C, Limit;
[Text(0, "n       phi     is prime^m^j");
for N:= 1 to 25 do
    [IntOut(0, N);  ChOut(0, 9\tab\);
    Phi:= Totient(N);
    IntOut(0, Phi);  ChOut(0, 9\tab\);
    Text(0, if Phi = N-1 then "true" else "false");
    CrLf(0);
    ];
CrLf(0);
for Pwr:= 2 to 4 do
    [C:= 0;
    Limit:= fix(Pow(10.0, float(Pwr)));
    IntOut(0, Limit);  ChOut(0, 9\tab\);
    for N:= 1 to Limit do
        [Phi:= Totient(N);
        if Phi = N-1 then C:= C+1;
        ];
    IntOut(0, C);  CrLf(0);
    ];
]
Output:
n       phi     is prime
1       1       false
2       1       true
3       2       true
4       2       false
5       4       true
6       2       false
7       6       true
8       4       false
9       6       false
10      4       false
11      10      true
12      4       false
13      12      true
14      6       false
15      8       false
16      8       false
17      16      true
18      6       false
19      18      true
20      8       false
21      12      false
22      10      false
23      22      true
24      8       false
25      20      false

100     25
1000    168
10000   1229

zkl

fcn totient(n){ [1..n].reduce('wrap(p,k){ p + (n.gcd(k)==1) }) }
fcn isPrime(n){ totient(n)==(n - 1) }
foreach n in ([1..25]){
   println("\u03c6(%2d) ==%3d %s"
      .fmt(n,totient(n),isPrime(n) and "is prime" or ""));
}
Output:
φ( 1) ==  1 
φ( 2) ==  1 is prime
φ( 3) ==  2 is prime
φ( 4) ==  2 
φ( 5) ==  4 is prime
φ( 6) ==  2 
φ( 7) ==  6 is prime
φ( 8) ==  4 
φ( 9) ==  6 
φ(10) ==  4 
φ(11) == 10 is prime
φ(12) ==  4 
φ(13) == 12 is prime
φ(14) ==  6 
φ(15) ==  8 
φ(16) ==  8 
φ(17) == 16 is prime
φ(18) ==  6 
φ(19) == 18 is prime
φ(20) ==  8 
φ(21) == 12 
φ(22) == 10 
φ(23) == 22 is prime
φ(24) ==  8 
φ(25) == 20 
count:=0;
foreach n in ([1..10_000]){	// yes, this is sloooow
   count+=isPrime(n);
   if(n==100 or n==1000 or n==10_000)
      println("Primes <= %,6d : %,5d".fmt(n,count));
}
Output:
Primes <=    100 :    25
Primes <=  1,000 :   168
Primes <= 10,000 : 1,229