Skip to content

Commit

Permalink
Problem 69: Totient maximum
Browse files Browse the repository at this point in the history
  • Loading branch information
pbevin committed Dec 18, 2013
1 parent 93086f5 commit 55c3fdc
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
63 changes: 63 additions & 0 deletions eu069.c
@@ -0,0 +1,63 @@
#include "euler.h"

static int primes[1000000];
static int nprimes;
static int cachedphi[1000000];

static int phi(int n) {
int p;
for (int i = 0; i < nprimes && ((p = primes[i]) < n); i++) {
if (n % p == 0) {
// If p and n/p are coprime, we can multiply them,
// otherwise we have to cast out factors of p.
if (n % (p*p) != 0) {
return (cachedphi[n] = cachedphi[n / p] * cachedphi[p]);
} else {
int k = 2;
int divisor = p*p;
do {
k++;
divisor *= p;
} while (n % divisor == 0);
divisor /= p;

// phi(p^k) = p^k-p^{k-1} and phi(n) = phi(n/p^k) * phi(p^k)
int phi_p_k = divisor - divisor / p;

return (cachedphi[n] = cachedphi[n / divisor] * phi_p_k);
}
}
}

// phi(p) = p-1 when p is prime
return (cachedphi[n] = n-1);
}

static double n_over_phi_n(int n) {
double d = n;
d /= phi(n);
return d;
}

void eu069(char *ans) {
const int N = 1000000;
/* const int N = 20; */

double max = 0;
int n_of_max = 0;

nprimes = genprimes(primes, N);

cachedphi[1] = 1;

for (int n = 2; n < N; n++) {
double v = n_over_phi_n(n);
/* printf("%d: %d %g\n", n, phi(n), v); */
if (v > max) {
max = v;
n_of_max = n;
}
}

sprintf(ans, "%d", n_of_max);
}
1 change: 1 addition & 0 deletions euler.c
Expand Up @@ -253,6 +253,7 @@ struct puzzle puzzles[] = {
{ "066", &eu066, "661" },
{ "067", &eu067, "7273" },
{ "068", &eu068, "6531031914842725" },
{ "069", &eu069, NULL },
};

#define NPUZZLES (sizeof puzzles / sizeof(puzzles[0]))
Expand Down

0 comments on commit 55c3fdc

Please sign in to comment.