From ec1fae253d4d6cdf7be74b1d4b2f9f9030e3a1c3 Mon Sep 17 00:00:00 2001 From: Philippe Zwietering Date: Sun, 14 Nov 2021 21:24:24 +0100 Subject: [PATCH] Finished 69 (nice), wasn't too hard but my solution is pretty slow for some reason (19 s) --- projecteuler/069/main.cpp | 101 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 projecteuler/069/main.cpp diff --git a/projecteuler/069/main.cpp b/projecteuler/069/main.cpp new file mode 100644 index 0000000..206cd81 --- /dev/null +++ b/projecteuler/069/main.cpp @@ -0,0 +1,101 @@ +/* Totient maximum + +Euler's Totient function, φ(n) [sometimes called the phi function], is used to determine the number of numbers less than 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. + +It can be seen that n=6 produces a maximum n/φ(n) for n ≤ 10. + +Find the value of n ≤ 1,000,000 for which n/φ(n) is a maximum. + +*/ + +#include + +using namespace std; + +const int MAX = 1000000; + +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 primes = vector()){ + if(primes.empty()){ + primes = sieve(n); + } + + vector result; + + for(int p : primes){ + if(p > n){ + break; + } + + if(n % p == 0){ + result.push_back(p); + + while(n % p == 0){ + n /= p; + } + } + } + + return result; +} + +int main(){ + + cout << "Hello this is Patrick" << endl; + auto start = chrono::high_resolution_clock::now(); + + vector n_phi(MAX + 1, 0); + auto primes = sieve(MAX); + + for(auto p : primes){ + n_phi[p] = 1 + 1 / ((float)p - 1); + } + + int n_max = 0; + float n_phi_max = 0; + + for(size_t i = 2; i < n_phi.size(); ++i){ + if(n_phi[i] == 0){ + auto terms = prime_terms(i, primes); + float acc = 1; + + for(int t : terms){ + acc *= n_phi[t]; + } + n_phi[i] = acc; + + if(n_phi_max < acc){ + n_max = i; + n_phi_max = acc; + } + } + + // cout << i << " " << n_phi[i] << endl; + } + + cout << n_max << endl; + + auto duration = chrono::duration_cast(chrono::high_resolution_clock::now() - start); + cout << (float)duration.count()/1000 << endl; + return 0; +}