diff --git a/.gitignore b/.gitignore index 5dc5f94..f5f57a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ Python/__pycache__ +ProblemsOverviews/* diff --git a/C/p009.c b/C/p009.c index d0ff0d1..9232e3b 100644 --- a/C/p009.c +++ b/C/p009.c @@ -27,7 +27,7 @@ int main(int argc, char **argv) { for(n = 1; n < m && !found; n++) { - if(gcd(m, n) == 1 && (m % 2 == 0 && n % 2 != 0 || m % 2 != 0 && n % 2 == 0)) + if(gcd(m, n) == 1 && ((m % 2 == 0 && n % 2 != 0) || (m % 2 != 0 && n % 2 == 0))) { a = m * m - n * n; b = 2 * m * n; diff --git a/C/p018.c b/C/p018.c index 52a7a68..5704467 100644 --- a/C/p018.c +++ b/C/p018.c @@ -77,7 +77,7 @@ int main(int argc, char **argv) /* Use the function implemented in projecteuler.c to find the maximum path.*/ max = find_max_path(triang, 15); - for(i = 0; i < 100; i++) + for(i = 0; i < 15; i++) { free(triang[i]); } diff --git a/C/p031.c b/C/p031.c index 84c8d8e..2cc77e0 100644 --- a/C/p031.c +++ b/C/p031.c @@ -49,7 +49,7 @@ int count(int value, int n, int i) if(value == 200) { - return n+1; + return n + 1; } else if(value > 200) { diff --git a/C/p062.c b/C/p062.c index ca35af4..118374e 100644 --- a/C/p062.c +++ b/C/p062.c @@ -85,7 +85,7 @@ int count_digits(long int a) return count; } -int is_permutation(int a, int b) +int is_permutation(long int a, long int b) { int i; int digits1[10] = {0}, digits2[10] = {0}; diff --git a/C/p070.c b/C/p070.c index af6ed84..beae7e5 100644 --- a/C/p070.c +++ b/C/p070.c @@ -27,7 +27,11 @@ int main(int argc, char **argv) clock_gettime(CLOCK_MONOTONIC, &start); - primes = sieve(N); + if((primes = sieve(N)) == NULL) + { + fprintf(stderr, "Error! Sieve function returned NULL\n"); + return 1; + } for(i = 2; i < N; i++) { diff --git a/C/p071.c b/C/p071.c new file mode 100644 index 0000000..48bf01b --- /dev/null +++ b/C/p071.c @@ -0,0 +1,64 @@ +/* Consider the fraction, n/d, where n and d are positive integers. If n +#include +#include +#include "projecteuler.h" + +#define N 1000000 + +int main(int argc, char **argv) +{ + int i, j, n, d, max_n; + double elapsed, max = 0.0; + struct timespec start, end; + + clock_gettime(CLOCK_MONOTONIC, &start); + + /* For each denominator q, we need to find the biggest numerator p for which + * p/q max) + { + n = j; + d = i; + max = (double)n / d; + + /* Reduce the fraction if it's not already reduced.*/ + if(gcd(i, j) > 1) + { + n /= gcd(i, j); + d /= gcd(i, j); + } + + max_n = n; + } + } + + clock_gettime(CLOCK_MONOTONIC, &end); + + elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000; + + printf("Project Euler, Problem 71\n"); + printf("Answer: %d\n", max_n); + + printf("Elapsed time: %.9lf seconds\n", elapsed); + + return 0; +} diff --git a/C/p072.c b/C/p072.c new file mode 100644 index 0000000..c3da000 --- /dev/null +++ b/C/p072.c @@ -0,0 +1,54 @@ +/* Consider the fraction, n/d, where n and d are positive integers. If n +#include +#include +#include +#include "projecteuler.h" + +#define N 1000001 + +int main(int argc, char **argv) +{ + int i; + int *primes; + long int count = 0; + double elapsed; + struct timespec start, end; + + clock_gettime(CLOCK_MONOTONIC, &start); + + if((primes = sieve(N)) == NULL) + { + fprintf(stderr, "Error! Sieve function returned NULL\n"); + return 1; + } + + /* For any denominator d, the number of reduced proper fractions is + * the number of fractions n/d where gcd(n, d)=1, which is the definition + * of Euler's Totient Function phi. It's sufficient to calculate phi for each + * denominator and sum the value.*/ + for(i = 2; i < N; i++) + { + count += phi(i, primes); + } + + clock_gettime(CLOCK_MONOTONIC, &end); + + elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000; + + printf("Project Euler, Problem 72\n"); + printf("Answer: %ld\n", count); + + printf("Elapsed time: %.9lf seconds\n", elapsed); + + return 0; +} diff --git a/C/p073.c b/C/p073.c new file mode 100644 index 0000000..82821fb --- /dev/null +++ b/C/p073.c @@ -0,0 +1,51 @@ +/* Consider the fraction, n/d, where n and d are positive integers. If n +#include +#include +#include "projecteuler.h" + +int main(int argc, char **argv) +{ + int i, j, limit, count = 0; + double elapsed; + struct timespec start, end; + + clock_gettime(CLOCK_MONOTONIC, &start); + + /* For each denominator q, we need to find the fractions p/q for which + * 1/3

+#include +#include + +#define N 1000000 + +int factorial(int n); +int len_chain(int n); + +int factorials[10] = {0}; +int chains[N] = {0}; + +int main(int argc, char **argv) +{ + int i, count = 0; + double elapsed; + struct timespec start, end; + + clock_gettime(CLOCK_MONOTONIC, &start); + + /* Simple brute force approach, for every number calculate + * the length of the chain.*/ + for(i = 3; i < N; i++) + { + if(len_chain(i) == 60) + { + count++; + } + } + + clock_gettime(CLOCK_MONOTONIC, &end); + + elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000; + + printf("Project Euler, Problem 74\n"); + printf("Answer: %d\n", count); + + printf("Elapsed time: %.9lf seconds\n", elapsed); + + return 0; +} + +/* Recursively calculate the factorial, of a number, saving the result + * so that it can be reused later.*/ +int factorial(int n) +{ + if(n == 0 || n == 1) + { + return 1; + } + else if(factorials[n] != 0) + { + return factorials[n]; + } + else + { + factorials[n]=n*factorial(n-1); + return factorials[n]; + } +} + +int len_chain(int n) +{ + int i, count = 0, finished = 0, value, tmp; + int chain[60]; + + value = n; + chain[count] = value; + + while(!finished) + { + tmp = 0; + count++; + + /* Generate the next number of the chain by taking + * the digits of the current value, calculating the + * factorials and adding them.*/ + while(value != 0) + { + tmp += factorial(value % 10); + value /= 10; + } + + /* If the chain length for the new value has already been + * calculated before, use the saved value (only chains for + * values smaller than N are saved).*/ + if(tmp < N && chains[tmp] != 0) + { + return count + chains[tmp]; + } + + value = tmp; + + /* If the current value is already present in the chain, + * the chain is finished.*/ + for(i = 0; i < count; i++) + { + if(chain[i] == value) + { + finished = 1; + } + } + + chain[count] = value; + } + + chains[n] = count; + + return count; +} diff --git a/C/p075.c b/C/p075.c new file mode 100644 index 0000000..ce467f3 --- /dev/null +++ b/C/p075.c @@ -0,0 +1,102 @@ +/* It turns out that 12 cm is the smallest length of wire that can be bent to form an integer sided right angle triangle in exactly one way, + * but there are many more examples. + * + * 12 cm: (3,4,5) + * 24 cm: (6,8,10) + * 30 cm: (5,12,13) + * 36 cm: (9,12,15) + * 40 cm: (8,15,17) + * 48 cm: (12,16,20) + * + * In contrast, some lengths of wire, like 20 cm, cannot be bent to form an integer sided right angle triangle, and other lengths allow + * more than one solution to be found; for example, using 120 cm it is possible to form exactly three different integer sided right angle triangles. + * + * 120 cm: (30,40,50), (20,48,52), (24,45,51) + * + * Given that L is the length of the wire, for how many values of L ≤ 1,500,000 can exactly one integer sided right angle triangle be formed?*/ + +#include +#include +#include +#include "projecteuler.h" + +#define N 1500000 + +int main(int argc, char **argv) +{ + int i, a, b, c, tmpa, tmpb, tmpc, m, n, count = 0; + int *l; + double elapsed; + struct timespec start, end; + + clock_gettime(CLOCK_MONOTONIC, &start); + + if((l = (int *)calloc(N + 1, sizeof(int))) == NULL) + { + fprintf(stderr, "Error while allocating memory\n"); + return 1; + } + + /* Generate all Pythagorean triplets using Euclid's algorithm: + * For m>=2 and n +#include +#include + +int count(int value, int n, int i); + +int integers[99]; + +int main(int argc, char **argv) +{ + int i, n; + double elapsed; + struct timespec start, end; + + clock_gettime(CLOCK_MONOTONIC, &start); + + for(i = 0; i < 99; i++) + integers[i] = i + 1; + + n = count(0, 0, 0); + + clock_gettime(CLOCK_MONOTONIC, &end); + + elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000; + + printf("Project Euler, Problem 76\n"); + printf("Answer: %d\n", n); + + printf("Elapsed time: %.9lf seconds\n", elapsed); + + return 0; +} + +int count(int value, int n, int i) +{ + int j; + + for(j = i; j < 99; j++) + { + value += integers[j]; + + if(value == 100) + { + return n + 1; + } + else if(value > 100) + { + return n; + } + else + { + n = count(value, n, j); + value -= integers[j]; + } + } + + return n; +} diff --git a/C/projecteuler.c b/C/projecteuler.c index 8e0bd60..c7a0c22 100644 --- a/C/projecteuler.c +++ b/C/projecteuler.c @@ -690,3 +690,96 @@ int phi_semiprime(int n, int p, int q) return n - (p + q) + 1; } } + +/* Function to calculate phi(n) for any n. If n is prime, phi(n)=n-1, + * is n is semiprime, use the above function. In any other case, + * phi(n)=n*prod(1-1/p) for every distinct prime p that divides n.*/ +int phi(int n, int *primes) +{ + int i, p, q, limit; + double ph = (double)n; + + /* If n is prime, phi(n)=n-1*/ + if(primes[n]) + { + return n - 1; + } + + /* If n is semiprime, use above function.*/ + if(is_semiprime(n, &p, &q, primes)) + { + return phi_semiprime(n, p, q); + } + + /* If 2 is a factor of n, multiply the current ph (which now is n) + * by 1-1/2, then divide all factors 2.*/ + if(n % 2 == 0) + { + ph *= (1.0 - 1.0 / 2.0); + + do + { + n /= 2; + }while(n % 2 == 0); + } + + /* If 3 is a factor of n, multiply the current ph by 1-1/3, + * then divide all factors 3.*/ + if(n % 3 == 0) + { + ph *= (1.0 - 1.0 / 3.0); + + do + { + n /= 3; + }while(n % 3 == 0); + } + + /*Any number can have only one prime factor greater than its + * square root, so we can stop checking at this point and deal + * with the only factor larger than sqrt(n), if present, at the end.*/ + limit = floor(sqrt(n)); + + /* Every prime other than 2 and 3 is in the form 6k+1 or 6k-1. + * If I check all those value no prime factors of the number + * will be missed. For each of these possible primes, check if + * they are prime, then check if the number divides n, in which + * case update the current ph.*/ + for(i = 5; i <= limit; i += 6) + { + if(primes[i]) + { + if(n % i == 0) + { + ph *= (1.0 - 1.0 / i); + + do + { + n /= i; + }while(n % i == 0); + } + } + if(primes[i+2]) + { + if(n % (i + 2) == 0) + { + ph *= (1.0 - 1.0 /(i + 2)); + + do + { + n /= (i + 2); + }while(n % (i + 2) == 0); + } + } + } + + /* After dividing all prime factors smaller than sqrt(n), n is either 1 + * or is equal to the only prime factor greater than sqrt(n). In this + * second case, we need to update ph with the last prime factor.*/ + if(n > 1) + { + ph *= (1.0 - 1.0 / n); + } + + return (int)ph; +} diff --git a/C/projecteuler.h b/C/projecteuler.h index e81da04..a8315b3 100644 --- a/C/projecteuler.h +++ b/C/projecteuler.h @@ -23,5 +23,6 @@ int *build_sqrt_cont_fraction(int i, int *period, int l); int pell_eq(int i, mpz_t x); int is_semiprime(int n, int *p, int *q, int *primes); int phi_semiprime(int n, int p, int q); +int phi(int n, int *primes); #endif diff --git a/Python/p033.py b/Python/p033.py index 2243a3c..72ac514 100644 --- a/Python/p033.py +++ b/Python/p033.py @@ -10,8 +10,9 @@ # # If the product of these four fractions is given in its lowest common terms, find the value of the denominator. +from math import gcd + from timeit import default_timer -from projecteuler import gcd def main(): start = default_timer() diff --git a/Python/p071.py b/Python/p071.py new file mode 100644 index 0000000..42aaaba --- /dev/null +++ b/Python/p071.py @@ -0,0 +1,54 @@ +#!/usr/bin/python3 + +# Consider the fraction, n/d, where n and d are positive integers. If n max_: + n = j + d = i + max_ = n / d + +# Reduce the fractions if it's not already reduced. + if gcd(i, j) > 1: + n /= gcd(i, j) + d /= gcd(i, j) + + max_n = n + + end = default_timer() + + print('Project Euler, Problem 71') + print('Answer: {}'.format(max_n)) + + print('Elapsed time: {:.9f} seconds'.format(end - start)) + +if __name__ == '__main__': + main() diff --git a/Python/p072.py b/Python/p072.py new file mode 100644 index 0000000..968de9e --- /dev/null +++ b/Python/p072.py @@ -0,0 +1,39 @@ +#!/usr/bin/python3 + +# Consider the fraction, n/d, where n and d are positive integers. If n=2 and n 1: + ph = ph * (1 - 1 / n) + + return ph