Tim Varley Logo
Tim Varley Principal AI Engineer and Tech Leader
Problem #70 hard

Totient Permutation

Euler's totient function, ϕ(n)\phi(n) [sometimes called the phi function], is used to determine the number of positive numbers less than or equal to nn which are relatively prime to nn. For example, as 1,2,4,5,71, 2, 4, 5, 7, and 88, are all less than nine and relatively prime to nine, ϕ(9)=6\phi(9)=6.The number 11 is considered to be relatively prime to every positive number, so ϕ(1)=1\phi(1)=1.

Interestingly, ϕ(87109)=79180\phi(87109)=79180, and it can be seen that 8710987109 is a permutation of 7918079180.

Find the value of nn, 1<n<1071 \lt n \lt 10^7, for which ϕ(n)\phi(n) is a permutation of nn and the ratio n/ϕ(n)n/\phi(n) produces a minimum.

View on Project Euler

Implementations

cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <limits>
int totient_permutation()
{
const int MAXN = 10000000;
std::vector<long long> phi(MAXN+1);
for(int i=0; i<=MAXN; i++) phi[i] = i;
for(int i=2; i<=MAXN; i++){
if(phi[i] == i){ // prime
for(long long j=i; j<=MAXN; j+=i){
phi[j] = phi[j] / i * (i-1);
}
}
}
double min_ratio = std::numeric_limits<double>::max();
int result = -1;
for(int n=2; n<=MAXN; n++){
std::string s1 = std::to_string(n);
std::string s2 = std::to_string(phi[n]);
if(s1.length() != s2.length()) continue;
std::sort(s1.begin(), s1.end());
std::sort(s2.begin(), s2.end());
if(s1 == s2){
double ratio = (double)n / phi[n];
if(ratio < min_ratio){
min_ratio = ratio;
result = n;
}
}
}
return result;
}
#if ! defined UNITTEST_MODE
int main(int argc, char const *argv[])
{
std::cout << "Answer: " << totient_permutation() << std::endl;
}
#endif // #if ! defined UNITTEST_MODE
View on GitHub
O(N log log N) time, O(N) space (sieve approach with permutation checks)
tvarley.github.io/src/content/euler/problem-070.md