Perl 6, 47 45 44 43 42 41 39 bytes
{($^x,{+(^$^x .grep: {$_ gcd$x==1})}...*)[$^n]}
{($^x,{+(^$^x Xgcd $x).grep: *==1}...*)[$^n]}
{($^x,{+grep *==1,(^$^x Xgcd $x)}...*)[$^n]}
{($^x,{+grep *==1,(^$^x Xgcd$x)}...*)[$^n]}
{($^x,{+grep 2>*,(^$^x Xgcd$x)}...*)[$^n]}
{($^x,{+grep 2>*,(^$_ Xgcd$_)}...*)[$^n]}
{($^x,{sum 2 X>(^$_ Xgcd$_)}...*)[$^n]}
Explanation:
{ # parameters are $n,$x ( declared as placeholder parameters )
(
$^x, # seed sequence generator with second argument
{ # parameter is $_
sum
2
X[>] # crossed compared using &infix«>»
(
0 ..^ $_ # from 0 up to and excluding the parameter
X[gcd] # cross apply &infix:<gcd> with:
$_ # the parameter
)
}
... # keep applying that block
* # forever
)[ $^n ] # grab the one at the index indicated by the first argument
}
Test:
use v6.c;
use Test;
my @tests = (
(1, 10) => 4,
(2, 10) => 2,
(3, 10) => 1,
(1,100) => 40,
(2,100) => 16,
(3,100) => 8,
(4,100) => 4,
(5,100) => 2,
(6,100) => 1,
);
plan +@tests;
my &repeated-totient = {($^x,{sum 2 X>(^$_ Xgcd$_)}...*)[$^n]}
for @tests -> $_ ( :key(@input), :value($expected) ) {
is repeated-totient(|@input), $expected, .gist
}
1..9
ok 1 - (1 10) => 4
ok 2 - (2 10) => 2
ok 3 - (3 10) => 1
ok 4 - (1 100) => 40
ok 5 - (2 100) => 16
ok 6 - (3 100) => 8
ok 7 - (4 100) => 4
ok 8 - (5 100) => 2
ok 9 - (6 100) => 1