Project-Euler / 461
Problem 461 asks:
Let \(f_n(k) = e^{k/n} - 1\), for all non-negative integers \(k\).
Let \(g(n) = a^2 + b^2 + c^2 + d^2\) for \(a, b, c, d\) that minimize: \(| f_n(a) + f_n(b) + f_n(c) + f_n(d) - \pi |\).
Find \(g(10000)\).
I solved this using C:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SIZE (15000/2 * (15000 + 1))
#define PI 3.14159265358979323846
int cmp (const void *a, const void *b) {
const double *da = (const double *) a;
const double *db = (const double *) b;
return (da > db) - (da < db);
}
int main (void) {
double *sums, f[15000], bestError;
int a, b, c, d, bestI, bestMid;
for (int i = 0; i < 15000; i++) {
f[i] = exp((double)i/10000) - 1;
}
sums = malloc(SIZE * sizeof(double));
for (int i = 0, k = 0; i < 15000; i++) {
for (int j = i; j < 15000; j++) {
sums[k++] = f[i] + f[j];
}
}
qsort(sums, SIZE, sizeof(double), cmp);
bestError = 1;
for (int i = 0; i < SIZE; i++) {
int min = 0;
int max = SIZE;
int mid;
while (max >= min) {
mid = (min + max) / 2;
if (sums[i] + sums[mid] <= PI) min = mid + 1;
else max = mid -1;
}
double error = fabs(sums[i] + sums[mid] - PI);
if (error < bestError) {
bestError = error;
bestI = i;
bestMid = mid;
}
}
for (int i = 0; i < 15000; i++) {
for (int j = i; j < 15000; j++) {
if (sums[bestI] == f[i] + f[j]) {
a = i;
b = j;
}
if (sums[bestMid] == f[i] + f[j]) {
c = i;
d = j;
}
}
}
printf("%d² + %d² + %d² + %d² = %d\n", a, b, c, d, a*a + b*b + c*c + d*d);
return 0;
}
It runs in 23 seconds (on a 3.5 GHz CPU).