From 20237a22af46bf1a2190a57c1ac87af41496d838 Mon Sep 17 00:00:00 2001 From: Philippe Zwietering Date: Sun, 14 Nov 2021 22:25:02 +0100 Subject: [PATCH] Finished 070, by using the way quicker prime factorization it is done in 18 seconds --- projecteuler/070/main.cpp | 103 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 projecteuler/070/main.cpp diff --git a/projecteuler/070/main.cpp b/projecteuler/070/main.cpp new file mode 100644 index 0000000..c3877c9 --- /dev/null +++ b/projecteuler/070/main.cpp @@ -0,0 +1,103 @@ +/* + +Totient permutation + +Euler's Totient function, φ(n) [sometimes called the phi function], is used to determine the number of positive numbers less than or equal to n which are relatively prime to n. For example, as 1, 2, 4, 5, 7, and 8, are all less than nine and relatively prime to nine, φ(9)=6. +The number 1 is considered to be relatively prime to every positive number, so φ(1)=1. + +Interestingly, φ(87109)=79180, and it can be seen that 87109 is a permutation of 79180. + +Find the value of n, 1 < n < 107, for which φ(n) is a permutation of n and the ratio n/φ(n) produces a minimum. + +*/ + +#include + +using namespace std; + +const int MAX = pow(10, 7); + +vector sieve(int n){ + vector numbers(n+1, true); + vector result; + + int i = 2; + while(i <= n){ + if(numbers[i]){ + result.push_back(i); + + int j = 2 * i; + while(j <= n){ + numbers[j] = false; + j += i; + } + } + ++i; + } + + return result; +} + +vector prime_terms(int n){ + vector result; + + if(n % 2 == 0){ + result.push_back(2); + + while(n % 2 == 0){ + n /= 2; + } + } + + for(int i = 3; i <= sqrt(n); i += 2){ + if(n % i == 0){ + result.push_back(i); + + while(n % i == 0){ + n /= i; + } + } + } + + if(n > 2){ + result.push_back(n); + } + + return result; +} + +int main(){ + + cout << "Hello this is Patrick" << endl; + auto start = chrono::high_resolution_clock::now(); + + int n_min = 0; + float min_ratio = 2; + + for(int n = 2; n < MAX; ++n){ + auto terms = prime_terms(n); + + float phi = n; + for(float term : terms){ + phi *= 1.0 - 1.0 / term; + } + + int p = phi; + string s_phi = to_string(p), s_n = to_string(n); + sort(s_phi.begin(), s_phi.end()); + sort(s_n.begin(), s_n.end()); + + if(s_phi == s_n){ + if((float)n / phi < min_ratio){ + min_ratio = (float)n / phi; + n_min = n; + } + } + } + + cout << n_min << endl; + + auto duration = chrono::duration_cast(chrono::high_resolution_clock::now() - start); + cout << (float)duration.count()/1000 << endl; + return 0; +}