87 lines
2.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* There are exactly ten ways of selecting three from five, 12345:
*
* 123, 124, 125, 134, 135, 145, 234, 235, 245, and 345
*
* In combinatorics, we use the notation, (5 3) = 10.
*
* In general, (n r)=n!/(r!(nr)!), where r≤n, n!=n×(n1)×...×3×2×1, and 0!=1.
*
* It is not until n=23, that a value exceeds one-million: (23 10)=1144066.
*
* How many, not necessarily distinct, values of (n r) for 1≤n≤100, are greater than one-million?*/
#define _POSIX_C_SOURCE 199309L
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <gmp.h>
#define N 100
#define LIMIT 1000000
void binomial(mpz_t bin, unsigned long int n, unsigned long int k, mpz_t *factorials);
int main(int argc, char **argv)
{
int i, j, count = 0;
double elapsed;
struct timespec start, end;
mpz_t bin;
mpz_t factorials[N+1];
clock_gettime(CLOCK_MONOTONIC, &start);
mpz_init(bin);
mpz_init_set_ui(factorials[0], 1);
/* Straightforward brute force approach, using the GMP Library. First
* calculate all factorials, then use them for the binomial coefficients.*/
for(i = 1; i <= N; i++)
{
mpz_init(factorials[i]);
mpz_fac_ui(factorials[i], i);
}
for(i = 23; i <= N; i++)
{
for(j = 1; j <= i; j++)
{
binomial(bin, i, j, factorials);
if(mpz_cmp_ui(bin, LIMIT) > 0)
count++;
}
}
mpz_clear(bin);
clock_gettime(CLOCK_MONOTONIC, &end);
elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000;
printf("Project Euler, Problem 53\n");
printf("Answer: %d\n", count);
printf("Elapsed time: %.9lf seconds\n", elapsed);
return 0;
}
void binomial(mpz_t bin, unsigned long n, unsigned long int k, mpz_t *factorials)
{
mpz_t num, d1, d2;
mpz_inits(num, d1, d2, NULL);
mpz_set(num, factorials[n]);
mpz_set(d1, factorials[k]);
mpz_set(d2, factorials[n-k]);
mpz_mul(d1, d1, d2);
mpz_tdiv_q(bin, num, d1);
mpz_clears(num, d1, d2, NULL);
}