diff --git a/C/p018.c b/C/p018.c index 3ca501c..52a7a68 100644 --- a/C/p018.c +++ b/C/p018.c @@ -74,9 +74,16 @@ int main(int argc, char **argv) fclose(fp); - /* Use function implemented in projecteuler.c to find the maximum path.*/ + /* Use the function implemented in projecteuler.c to find the maximum path.*/ max = find_max_path(triang, 15); + for(i = 0; i < 100; i++) + { + free(triang[i]); + } + + free(triang); + clock_gettime(CLOCK_MONOTONIC, &end); elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000; diff --git a/C/p049.c b/C/p049.c index 0bba891..685a28e 100644 --- a/C/p049.c +++ b/C/p049.c @@ -14,7 +14,7 @@ #define N 10000 -int check_digits(int a, int b); +int is_permutation(int a, int b); int *primes; @@ -45,7 +45,7 @@ int main(int argc, char **argv) /* If i, i+j and i+2*j are all primes and they have * all the same digits, the result has been found.*/ if(i + 2 * j < N && primes[i+j] && primes[i+2*j] && - check_digits(i, i+j) && check_digits(i, i+2*j)) + is_permutation(i, i+j) && is_permutation(i, i+2*j)) { found = 1; break; @@ -73,23 +73,26 @@ int main(int argc, char **argv) return 0; } -int check_digits(int a, int b) +int is_permutation(int a, int b) { int i; int digits1[10] = {0}, digits2[10] = {0}; + /* Get digits of a.*/ while(a > 0) { digits1[a%10]++; a /= 10; } + /* Get digits of b.*/ while(b > 0) { digits2[b%10]++; b /= 10; } + /* If they're not the same, return 0.*/ for(i = 0; i < 10; i++) { if(digits1[i] != digits2[i]) diff --git a/C/p052.c b/C/p052.c index 2334845..318ae1b 100644 --- a/C/p052.c +++ b/C/p052.c @@ -6,7 +6,7 @@ #include #include -int have_same_digits(int a, int b); +int is_permutation(int a, int b); int main(int argc, char **argv) { @@ -21,8 +21,8 @@ int main(int argc, char **argv) /* Brute force approach, try every integer number until the desired one is found.*/ while(1) { - if(have_same_digits(i, 2*i) && have_same_digits(i, 3*i) && have_same_digits(i, 4*i) && - have_same_digits(i, 5*i) && have_same_digits(i, 6*i)) + if(is_permutation(i, 2*i) && is_permutation(i, 3*i) && is_permutation(i, 4*i) && + is_permutation(i, 5*i) && is_permutation(i, 6*i)) { break; } @@ -42,7 +42,7 @@ int main(int argc, char **argv) return 0; } -int have_same_digits(int a, int b) +int is_permutation(int a, int b) { int i; int digits1[10] = {0}, digits2[10] = {0}; diff --git a/C/p062.c b/C/p062.c index e368524..ca35af4 100644 --- a/C/p062.c +++ b/C/p062.c @@ -9,7 +9,7 @@ #define N 10000 -int check_digits(long int a, long int b); +int is_permutation(long int a, long int b); int count_digits(long int a); int main(int argc, char **argv) @@ -38,7 +38,7 @@ int main(int argc, char **argv) * they can't be permutations).*/ for(j = i + 1; j < N && count_digits(cubes[j]) == count_digits(cubes[i]); j++) { - if(check_digits(cubes[i], cubes[j])) + if(is_permutation(cubes[i], cubes[j])) { count++; } @@ -85,23 +85,26 @@ int count_digits(long int a) return count; } -int check_digits(long int a, long int b) +int is_permutation(int a, int b) { int i; int digits1[10] = {0}, digits2[10] = {0}; + /* Get digits of a.*/ while(a > 0) { digits1[a%10]++; a /= 10; } + /* Get digits of b.*/ while(b > 0) { digits2[b%10]++; b /= 10; } + /* If they're not the same, return 0.*/ for(i = 0; i < 10; i++) { if(digits1[i] != digits2[i]) diff --git a/C/p064.c b/C/p064.c index 337a3fd..e23fdc1 100644 --- a/C/p064.c +++ b/C/p064.c @@ -50,7 +50,8 @@ int is_square(int n); int main(int argc, char **argv) { - int i, count = 0; + int i, count = 0, period; + int *fraction; double elapsed; struct timespec start, end; @@ -60,12 +61,23 @@ int main(int argc, char **argv) { /* Perfect squares are obviously not represented as continued fractions. * For all other numbers, calculate their period and check if it's odd.*/ - if(!is_square(i) && period_cf(i) % 2 != 0) + if(!is_square(i)) { - count++; + if((fraction = build_sqrt_cont_fraction(i, &period, 300)) == NULL) + { + fprintf(stderr, "Error! Build_cont_fraction function returned NULL\n"); + return 1; + } + + if(period % 2 != 0) + { + count++; + } } } + free(fraction); + clock_gettime(CLOCK_MONOTONIC, &end); elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000; diff --git a/C/p065.c b/C/p065.c index 1102ef6..9c6cf20 100644 --- a/C/p065.c +++ b/C/p065.c @@ -77,7 +77,7 @@ int main(int argc, char **argv) clock_gettime(CLOCK_MONOTONIC, &end); - elapsed=(end.tv_sec-start.tv_sec)+(double)(end.tv_nsec-start.tv_nsec)/1000000000; + elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000; printf("Project Euler, Problem 65\n"); printf("Answer: %d\n", sum); diff --git a/C/p066.c b/C/p066.c new file mode 100644 index 0000000..3d42f2d --- /dev/null +++ b/C/p066.c @@ -0,0 +1,92 @@ +/* Consider quadratic Diophantine equations of the form: + * + * x^2 – Dy^2 = 1 + * + * For example, when D=13, the minimal solution in x is 649^2 – 13×180^2 = 1. + * + * It can be assumed that there are no solutions in positive integers when D is square. + * + * By finding minimal solutions in x for D = {2, 3, 5, 6, 7}, we obtain the following: + * + * 3^2 – 2×2^2 = 1 + * 2^2 – 3×1^2 = 1 + * 9^2 – 5×4^2 = 1 + * 5^2 – 6×2^2 = 1 + * 8^2 – 7×3^2 = 1 + * + * Hence, by considering minimal solutions in x for D ≤ 7, the largest x is obtained when D=5. + * + * Find the value of D ≤ 1000 in minimal solutions of x for which the largest value of x is obtained.*/ + +#include +#include +#include +#include +#include +#include "projecteuler.h" + +int is_square(int n); + +int main(int argc, char **argv) +{ + int i, max_d = -1; + mpz_t x, max; + double elapsed; + struct timespec start, end; + + clock_gettime(CLOCK_MONOTONIC, &start); + +// mpz_init(x); + mpz_init_set_ui(max, 0); + + for(i = 2; i <= 1000; i++) + { + if(!is_square(i)) + { + /* Solve the Diophantine equation x^2-D*y^2=1 (Pell equation)*/ + if(pell_eq(i, x) == -1) + { + fprintf(stderr, "Error! Pell_eq function failed\n"); + return 1; + } + + if(mpz_cmp(x, max) > 0) + { + mpz_set(max, x); + max_d = i; + } + } + } + + mpz_clears(x, max, NULL); + + clock_gettime(CLOCK_MONOTONIC, &end); + + elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000; + + printf("Project Euler, Problem 66\n"); + printf("Answer: %d\n", max_d); + + printf("Elapsed time: %.9lf seconds\n", elapsed); + + return 0; +} + +int is_square(int n) +{ + int m; + double p; + + p = sqrt(n); + m = p; + + if(p == m) + { + return 1; + } + else + { + return 0; + } +} + diff --git a/C/p067.c b/C/p067.c new file mode 100644 index 0000000..cc07110 --- /dev/null +++ b/C/p067.c @@ -0,0 +1,82 @@ +/* By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23. + * + * 3 + * 7 4 + * 2 4 6 + * 8 5 9 3 + * + * That is, 3 + 7 + 4 + 9 = 23. + * Find the maximum total from top to bottom in triangle.txt (right click and 'Save Link/Target As...'), a 15K text file containing a triangle + * with one-hundred rows. + * + * NOTE: This is a much more difficult version of Problem 18. It is not possible to try every route to solve this problem, as there are 299 altogether! + * If you could check one trillion (1012) routes every second it would take over twenty billion years to check them all. + * There is an efficient algorithm to solve it. ;o)*/ + +#include +#include +#include +#include "projecteuler.h" + +int main(int argc, char **argv) +{ + int i, j, max; + int **triang; + double elapsed; + FILE *fp; + struct timespec start, end; + + clock_gettime(CLOCK_MONOTONIC, &start); + + if((triang = (int **)malloc(100*sizeof(int *))) == NULL) + { + fprintf(stderr, "Error while allocating memory\n"); + return 1; + } + + for(i = 1; i <= 100; i++) + { + if((triang[i-1] = (int *)malloc(i*sizeof(int))) == NULL) + { + fprintf(stderr, "Error while allocating memory\n"); + return 1; + } + } + + if((fp = fopen("triangle.txt", "r")) == NULL) + { + fprintf(stderr, "Error while opening file %s\n", "triangle.txt"); + return 1; + } + + for(i = 1; i <= 100; i++) + { + for(j = 0; j < i; j++) + { + fscanf(fp, "%d", &triang[i-1][j]); + } + } + + fclose(fp); + + /* Use the function implemented in projecteuler.c to find the maximum path.*/ + max = find_max_path(triang, 100); + + for(i = 0; i < 100; i++) + { + free(triang[i]); + } + + free(triang); + + clock_gettime(CLOCK_MONOTONIC, &end); + + elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000; + + printf("Project Euler, Problem 67\n"); + printf("Answer: %d\n", max); + + printf("Elapsed time: %.9lf seconds\n", elapsed); + + return 0; +} diff --git a/C/p068.c b/C/p068.c new file mode 100644 index 0000000..4c538ce --- /dev/null +++ b/C/p068.c @@ -0,0 +1,217 @@ +/* Consider the following "magic" 3-gon ring, filled with the numbers 1 to 6, and each line adding to nine. + * + * 4 + * \ + * \ + * 3 + * / \ + * / \ + * 1------2------6 + * / + * / + * 5 + * + * Working clockwise, and starting from the group of three with the numerically lowest external node (4,3,2 in this example), + * each solution can be described uniquely. For example, the above solution can be described by the set: 4,3,2; 6,2,1; 5,1,3. + * + * It is possible to complete the ring with four different totals: 9, 10, 11, and 12. There are eight solutions in total. + * + * Total Solution Set + * 9 4,2,3; 5,3,1; 6,1,2 + * 9 4,3,2; 6,2,1; 5,1,3 + * 10 2,3,5; 4,5,1; 6,1,3 + * 10 2,5,3; 6,3,1; 4,1,5 + * 11 1,4,6; 3,6,2; 5,2,4 + * 11 1,6,4; 5,4,2; 3,2,6 + * 12 1,5,6; 2,6,4; 3,4,5 + * 12 1,6,5; 3,5,4; 2,4,6 + * + * By concatenating each group it is possible to form 9-digit strings; the maximum string for a 3-gon ring is 432621513. + * + * Using the numbers 1 to 10, and depending on arrangements, it is possible to form 16- and 17-digit strings. What is the maximum 16-digit string + * for a "magic" 5-gon ring? + * + * O + * \ + * O + * / \ O + * / \ / + * O O + * / \ / + * O O--O---O + * \ + * O + */ + +#include +#include +#include +#include +#include +#include "projecteuler.h" + +int *eval_ring(int **ring, int n); +long int array_to_long(int *n, int len); +int compare(void *a, void *b); + +int main(int argc, char **argv) +{ + int i; + int *eval, **ring; + long int n, max = 0; + double elapsed; + struct timespec start, end; + + clock_gettime(CLOCK_MONOTONIC, &start); + + if((ring = (int **)malloc(10*sizeof(int *))) == NULL) + { + fprintf(stderr, "Error while allocating memory\n"); + return 1; + } + + for(i = 0; i < 10; i++) + { + if((ring[i] = (int *)malloc(sizeof(int))) == NULL) + { + fprintf(stderr, "Error while allocating memory\n"); + return 1; + } + *ring[i] = i + 1; + } + + /* Check if the first permutation of values is a possible solution.*/ + eval = eval_ring(ring, 5); + + /* Convert the vector into an integer number.*/ + n = array_to_long(eval, 15); + + if(n > max) + { + max = n; + } + + free(eval); + + /* Generate all possible permutations, for each one check if + * it's a possible solution for the ring and save the maximum.*/ + while(next_permutation((void **)ring, 10, compare) != -1) + { + eval = eval_ring(ring, 5); + + n = array_to_long(eval, 15); + + if(n > max) + { + max = n; + } + + free(eval); + } + + clock_gettime(CLOCK_MONOTONIC, &end); + + elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000; + + printf("Project Euler, Problem 68\n"); + printf("Answer: %ld\n", max); + + printf("Elapsed time: %.9lf seconds\n", elapsed); + + return 0; +} + +int compare(void *a, void *b) +{ + int *n1, *n2; + + n1 = (int *)a; + n2 = (int *)b; + + return *n1 - *n2; +} + +/* Function to evaluate the ring. The ring is represented as a vector of 2*n elements, + * the first n elements represent the external nodes of the ring, the next n elements + * represent the internal ring.*/ +int *eval_ring(int **ring, int n) +{ + int i, j, magic_val, val; + int *res; + + for(i = 1; i < n; i++) + { + /* We need to start from the lowest external node, so if + * the first element in the vector is not the lowest of + * the first n elements (the external elements), the configuration + * is not a valid one.*/ + if(*ring[i] < *ring[0]) + { + return NULL; + } + } + + if((res = (int *)malloc(3*n*sizeof(int))) == NULL) + { + fprintf(stderr, "Error while allocating memory\n"); + return NULL; + } + + /* Each group of three must have the same value.*/ + magic_val = *ring[0] + *ring[n] + *ring[n+1]; + + for(i = 0, j = 0; i < n; i++, j += 3) + { + /* We need to find the maximum 16-digit string, this is + * possible only if the element "10" is used only once, + * i.e. if it's one of the external nodes.*/ + if(*ring[n+i] == 10 || *ring[n+(i+1)%n] == 10) + { + return NULL; + } + + /* Check that the value of the current three-element group + * is the "magic" value.*/ + val = *ring[i] + *ring[n+i] + *ring[n+(i+1)%n]; + + if(val != magic_val) + { + return NULL; + } + + /* Save the current element group in the result string.*/ + res[j] = *ring[i]; + res[j+1] = *ring[n+i]; + res[j+2] = *ring[n+(i+1)%n]; + } + + return res; +} + +/* Function to convert the vector into a long int.*/ +long int array_to_long(int *n, int len) +{ + int i, k = 0; + long int res = 0; + + if(n == NULL) + { + return 0; + } + + for(i = len - 1; i >= 0; i--) + { + res += n[i] * pow(10, k); + + if(n[i] >= 10) + { + k += 2; + } + else + { + k++; + } + } + + return res; +} diff --git a/C/p069.c b/C/p069.c new file mode 100644 index 0000000..a55cc23 --- /dev/null +++ b/C/p069.c @@ -0,0 +1,66 @@ +/* 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. + * + * n Relatively Prime φ(n) n/φ(n) + * 2 1 1 2 + * 3 1,2 2 1.5 + * 4 1,3 2 2 + * 5 1,2,3,4 4 1.25 + * 6 1,5 2 3 + * 7 1,2,3,4,5,6 6 1.1666... + * 8 1,3,5,7 4 2 + * 9 1,2,4,5,7,8 6 1.5 + * 10 1,3,7,9 4 2.5 + * + * 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 +#include +#include +#include +#include "projecteuler.h" + +#define N 1000000 + +int main(int argc, char **argv) +{ + int i, res = 1; + double elapsed; + struct timespec start, end; + + clock_gettime(CLOCK_MONOTONIC, &start); + + i = 1; + + /* Using Euler's formula, phi(n)=n*prod(1-1/p), where p are the distinct + * primes that divide n. So n/phi(n)=1/prod(1-1/p). To find the maximum + * value of this function, the denominator must be minimized. This happens + * when n has the most distinct small prime factor, i.e. to find the solution + * we need to multiply the smallest consecutive primes until the result is + * larger than 1000000.*/ + while(res < N) + { + i++; + + if(is_prime(i)) + { + res *= i; + } + } + + /* We need the previous value, because we want i<1000000.*/ + res /= i; + + clock_gettime(CLOCK_MONOTONIC, &end); + + elapsed = (end.tv_sec-start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000; + + printf("Project Euler, Problem 69\n"); + printf("Answer: %d\n", res); + + printf("Elapsed time: %.9lf seconds\n", elapsed); + + return 0; +} diff --git a/C/p070.c b/C/p070.c new file mode 100644 index 0000000..af6ed84 --- /dev/null +++ b/C/p070.c @@ -0,0 +1,93 @@ +/* Euler's Totient function, φ(n) [sometimes called the phi function], is used to determine the number of positive numbers + * less than or equal to 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. + * The number 1 is considered to be relatively prime to every positive number, so φ(1)=1. + * + * Interestingly, φ(87109)=79180, and it can be seen that 87109 is a permutation of 79180. + * + * Find the value of n, 1 < n < 10^7, for which φ(n) is a permutation of n and the ratio n/φ(n) produces a minimum.*/ + +#include +#include +#include +#include +#include +#include "projecteuler.h" + +#define N 10000000 + +int is_permutation(int a, int b); + +int main(int argc, char **argv) +{ + int i, a, b, p, n = -1; + int *primes; + double elapsed, min = DBL_MAX; + struct timespec start, end; + + clock_gettime(CLOCK_MONOTONIC, &start); + + primes = sieve(N); + + for(i = 2; i < N; i++) + { + /* When n is prime, phi(n)=(n-1), so to minimize n/phi(n) we should + * use n prime. But n-1 can't be a permutation of n. The second best + * bet is to use semiprimes. For a semiprime n=p*q, phi(n)=(p-1)(q-1). + * So we check if a number is semiprime, if yes calculate phi, finally + * check if phi(n) is a permutation of n and update the minimum if it's + * smaller.*/ + if(is_semiprime(i, &a, &b, primes)) + { + p = phi_semiprime(i, a, b); + + if(is_permutation(p, i) && (double)i / p < min) + { + n = i; + min = (double)i / p; + } + } + } + + clock_gettime(CLOCK_MONOTONIC, &end); + + elapsed = (end.tv_sec - start.tv_sec) + (double)(end.tv_nsec - start.tv_nsec) / 1000000000; + + printf("Project Euler, Problem 70\n"); + printf("Answer: %d\n", n); + + printf("Elapsed time: %.9lf seconds\n", elapsed); + + return 0; +} + +int is_permutation(int a, int b) +{ + int i; + int digits1[10] = {0}, digits2[10] = {0}; + + /* Get digits of a.*/ + while(a > 0) + { + digits1[a%10]++; + a /= 10; + } + + /* Get digits of b.*/ + while(b > 0) + { + digits2[b%10]++; + b /= 10; + } + + /* If they're not the same, return 0.*/ + for(i = 0; i < 10; i++) + { + if(digits1[i] != digits2[i]) + { + return 0; + } + } + + return 1; +} diff --git a/C/projecteuler.c b/C/projecteuler.c index 8801c54..8e0bd60 100644 --- a/C/projecteuler.c +++ b/C/projecteuler.c @@ -478,23 +478,215 @@ int is_pentagonal(long int n) * d_(n+1)=(S-m_(n+1)^2)/d_n * a_(n+1)=floor((sqrt(S)+m_(n+1))/d_(n+1))=floor((a_0+m_(n+1))/d_(n+1)) * if a_i=2*a_0, the algorithm ends.*/ -int period_cf(int n) +int *build_sqrt_cont_fraction(int i, int *period, int l) { - int mn = 0, mn1, dn = 1, dn1, a0, an, an1, count = 0; + int mn = 0, mn1, dn = 1, dn1, a0, an, an1, count = 0, j; + int *fraction; - a0 = floor(sqrt(n)); + if((fraction = (int *)malloc(l*sizeof(int))) == NULL) + { + return NULL; + } + + j = 0; + a0 = floor(sqrt(i)); an = a0; - + fraction[j] = an; + j++; + do { mn1 = dn * an - mn; - dn1 = (n - mn1 * mn1) / dn; + dn1 = (i - mn1 * mn1)/ dn; an1 = floor((a0+mn1)/dn1); mn = mn1; dn = dn1; an = an1; count++; + fraction[j] = an; + j++; }while(an != 2 * a0); - return count; + fraction[j] = -1; + + *period = count; + + return fraction; +} + +/* Function to solve the Diophantine equation in the form x^2-Dy^2=1 + * (Pell equation) using continued fractions.*/ +int pell_eq(int d, mpz_t x) +{ + int found = 0, j, period; + mpz_t n1, n2, n3, d1, d2, d3, sol, tmp; + int *fraction; + + /* Find the continued fraction for sqrt(d).*/ + if((fraction = build_sqrt_cont_fraction(d, &period, 100)) == NULL) + { + return -1; + } + + /* Calculate the first convergent of the continued fraction.*/ + mpz_init_set_ui(n1, 0); + mpz_init_set_ui(n2, 1); + mpz_init_set_ui(d1, 1); + mpz_init_set_ui(d2, 0); + mpz_inits(n3, d3, sol, tmp, NULL); + + j = 0; + mpz_mul_ui(n3, n2, fraction[j]); + mpz_add(n3, n3, n1); + mpz_mul_ui(d3, d2, fraction[j]); + mpz_add(d3, d3, d1); + j++; + + /* Check if x=n, y=d solve the equation x^2-Dy^2=1.*/ + mpz_mul(sol, n3, n3); + mpz_mul(tmp, d3, d3); + mpz_mul_ui(tmp, tmp, d); + mpz_sub(sol, sol, tmp); + + if(mpz_cmp_ui(sol, 1) == 0) + { + mpz_set(x, n3); + found = 1; + free(fraction); + mpz_clears(n1, n2, n3, d1, d2, d3, sol, tmp, NULL); + } + + /* Until a solution is found, calculate the next convergent + * and check if x=n and y=d solve the equation.*/ + while(!found) + { + mpz_set(n1, n2); + mpz_set(n2, n3); + mpz_set(d1, d2); + mpz_set(d2, d3); + mpz_mul_ui(n3, n2, fraction[j]); + mpz_add(n3, n3, n1); + mpz_mul_ui(d3, d2, fraction[j]); + mpz_add(d3, d3, d1); + + mpz_mul(sol, n3, n3); + mpz_mul(tmp, d3, d3); + mpz_mul_ui(tmp, tmp, d); + mpz_sub(sol, sol, tmp); + + if(mpz_cmp_ui(sol, 1) == 0) + { + mpz_set(x, n3); + found = 1; + free(fraction); + mpz_clears(n1, n2, n3, d1, d2, d3, sol, tmp, NULL); + } + + j++; + + if(fraction[j] == -1) + { + j = 1; + } + } + + return 0; +} + +/* Function to check if a number is semiprime. Parameters include + * pointers to p and q to return the factors values and a list of + * primes.*/ +int is_semiprime(int n, int *p, int *q, int *primes) +{ + int i, limit; + + /* If n is prime, it's not semiprime.*/ + if(primes[n]) + { + return 0; + } + + /* Check if n is semiprime and one of the factors is 2.*/ + if(n % 2 == 0) + { + if(primes[n/2]) + { + *p = 2; + *q = n / 2; + return 1; + } + else + { + return 0; + } + } + /* Check if n is semiprime and one of the factors is 3.*/ + else if(n % 3 == 0) + { + if(primes[n/3]) + { + *p = 3; + *q = n / 3; + return 1; + } + else + { + return 0; + } + } + + /*Any number can have only one prime factor greater than its + square root, so we can stop checking at this point.*/ + 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 if the number is semiprime with using + * that factor.*/ + for(i = 5; i <= limit; i += 6) + { + if(primes[i] && n % i == 0) + { + if(primes[n/i]) + { + *p = i; + *q = n / i; + return 1; + } + else + { + return 0; + } + } + else if(primes[i+2] && n % (i + 2) == 0) + { + if(primes[n/(i+2)]) + { + *p = i + 2; + *q = n / (i + 2); + return 1; + } + else + { + return 0; + } + } + } + + return 0; +} + +/* If n=pq is semiprime, phi(n)=(p-1)(q-1)=pq-p-q+1=n-(p+4)+1 + * if p!=q. If p=q (n is a square), phi(n)=n-p.*/ +int phi_semiprime(int n, int p, int q) +{ + if(p == q) + { + return n - p; + } + else + { + return n - (p + q) + 1; + } } diff --git a/C/projecteuler.h b/C/projecteuler.h index e87cf0c..e81da04 100644 --- a/C/projecteuler.h +++ b/C/projecteuler.h @@ -19,6 +19,9 @@ void quick_sort(void **array, int l, int r, int (*cmp)(void *lv, void *rv)); int next_permutation(void **perm, int n, int (*cmp)(void *a, void *b)); int is_pandigital(int value, int n); int is_pentagonal(long int n); -int period_cf(int n); +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); #endif diff --git a/C/triangle.txt b/C/triangle.txt new file mode 100644 index 0000000..00aa2bc --- /dev/null +++ b/C/triangle.txt @@ -0,0 +1,100 @@ +59 +73 41 +52 40 09 +26 53 06 34 +10 51 87 86 81 +61 95 66 57 25 68 +90 81 80 38 92 67 73 +30 28 51 76 81 18 75 44 +84 14 95 87 62 81 17 78 58 +21 46 71 58 02 79 62 39 31 09 +56 34 35 53 78 31 81 18 90 93 15 +78 53 04 21 84 93 32 13 97 11 37 51 +45 03 81 79 05 18 78 86 13 30 63 99 95 +39 87 96 28 03 38 42 17 82 87 58 07 22 57 +06 17 51 17 07 93 09 07 75 97 95 78 87 08 53 +67 66 59 60 88 99 94 65 55 77 55 34 27 53 78 28 +76 40 41 04 87 16 09 42 75 69 23 97 30 60 10 79 87 +12 10 44 26 21 36 32 84 98 60 13 12 36 16 63 31 91 35 +70 39 06 05 55 27 38 48 28 22 34 35 62 62 15 14 94 89 86 +66 56 68 84 96 21 34 34 34 81 62 40 65 54 62 05 98 03 02 60 +38 89 46 37 99 54 34 53 36 14 70 26 02 90 45 13 31 61 83 73 47 +36 10 63 96 60 49 41 05 37 42 14 58 84 93 96 17 09 43 05 43 06 59 +66 57 87 57 61 28 37 51 84 73 79 15 39 95 88 87 43 39 11 86 77 74 18 +54 42 05 79 30 49 99 73 46 37 50 02 45 09 54 52 27 95 27 65 19 45 26 45 +71 39 17 78 76 29 52 90 18 99 78 19 35 62 71 19 23 65 93 85 49 33 75 09 02 +33 24 47 61 60 55 32 88 57 55 91 54 46 57 07 77 98 52 80 99 24 25 46 78 79 05 +92 09 13 55 10 67 26 78 76 82 63 49 51 31 24 68 05 57 07 54 69 21 67 43 17 63 12 +24 59 06 08 98 74 66 26 61 60 13 03 09 09 24 30 71 08 88 70 72 70 29 90 11 82 41 34 +66 82 67 04 36 60 92 77 91 85 62 49 59 61 30 90 29 94 26 41 89 04 53 22 83 41 09 74 90 +48 28 26 37 28 52 77 26 51 32 18 98 79 36 62 13 17 08 19 54 89 29 73 68 42 14 08 16 70 37 +37 60 69 70 72 71 09 59 13 60 38 13 57 36 09 30 43 89 30 39 15 02 44 73 05 73 26 63 56 86 12 +55 55 85 50 62 99 84 77 28 85 03 21 27 22 19 26 82 69 54 04 13 07 85 14 01 15 70 59 89 95 10 19 +04 09 31 92 91 38 92 86 98 75 21 05 64 42 62 84 36 20 73 42 21 23 22 51 51 79 25 45 85 53 03 43 22 +75 63 02 49 14 12 89 14 60 78 92 16 44 82 38 30 72 11 46 52 90 27 08 65 78 03 85 41 57 79 39 52 33 48 +78 27 56 56 39 13 19 43 86 72 58 95 39 07 04 34 21 98 39 15 39 84 89 69 84 46 37 57 59 35 59 50 26 15 93 +42 89 36 27 78 91 24 11 17 41 05 94 07 69 51 96 03 96 47 90 90 45 91 20 50 56 10 32 36 49 04 53 85 92 25 65 +52 09 61 30 61 97 66 21 96 92 98 90 06 34 96 60 32 69 68 33 75 84 18 31 71 50 84 63 03 03 19 11 28 42 75 45 45 +61 31 61 68 96 34 49 39 05 71 76 59 62 67 06 47 96 99 34 21 32 47 52 07 71 60 42 72 94 56 82 83 84 40 94 87 82 46 +01 20 60 14 17 38 26 78 66 81 45 95 18 51 98 81 48 16 53 88 37 52 69 95 72 93 22 34 98 20 54 27 73 61 56 63 60 34 63 +93 42 94 83 47 61 27 51 79 79 45 01 44 73 31 70 83 42 88 25 53 51 30 15 65 94 80 44 61 84 12 77 02 62 02 65 94 42 14 94 +32 73 09 67 68 29 74 98 10 19 85 48 38 31 85 67 53 93 93 77 47 67 39 72 94 53 18 43 77 40 78 32 29 59 24 06 02 83 50 60 66 +32 01 44 30 16 51 15 81 98 15 10 62 86 79 50 62 45 60 70 38 31 85 65 61 64 06 69 84 14 22 56 43 09 48 66 69 83 91 60 40 36 61 +92 48 22 99 15 95 64 43 01 16 94 02 99 19 17 69 11 58 97 56 89 31 77 45 67 96 12 73 08 20 36 47 81 44 50 64 68 85 40 81 85 52 09 +91 35 92 45 32 84 62 15 19 64 21 66 06 01 52 80 62 59 12 25 88 28 91 50 40 16 22 99 92 79 87 51 21 77 74 77 07 42 38 42 74 83 02 05 +46 19 77 66 24 18 05 32 02 84 31 99 92 58 96 72 91 36 62 99 55 29 53 42 12 37 26 58 89 50 66 19 82 75 12 48 24 87 91 85 02 07 03 76 86 +99 98 84 93 07 17 33 61 92 20 66 60 24 66 40 30 67 05 37 29 24 96 03 27 70 62 13 04 45 47 59 88 43 20 66 15 46 92 30 04 71 66 78 70 53 99 +67 60 38 06 88 04 17 72 10 99 71 07 42 25 54 05 26 64 91 50 45 71 06 30 67 48 69 82 08 56 80 67 18 46 66 63 01 20 08 80 47 07 91 16 03 79 87 +18 54 78 49 80 48 77 40 68 23 60 88 58 80 33 57 11 69 55 53 64 02 94 49 60 92 16 35 81 21 82 96 25 24 96 18 02 05 49 03 50 77 06 32 84 27 18 38 +68 01 50 04 03 21 42 94 53 24 89 05 92 26 52 36 68 11 85 01 04 42 02 45 15 06 50 04 53 73 25 74 81 88 98 21 67 84 79 97 99 20 95 04 40 46 02 58 87 +94 10 02 78 88 52 21 03 88 60 06 53 49 71 20 91 12 65 07 49 21 22 11 41 58 99 36 16 09 48 17 24 52 36 23 15 72 16 84 56 02 99 43 76 81 71 29 39 49 17 +64 39 59 84 86 16 17 66 03 09 43 06 64 18 63 29 68 06 23 07 87 14 26 35 17 12 98 41 53 64 78 18 98 27 28 84 80 67 75 62 10 11 76 90 54 10 05 54 41 39 66 +43 83 18 37 32 31 52 29 95 47 08 76 35 11 04 53 35 43 34 10 52 57 12 36 20 39 40 55 78 44 07 31 38 26 08 15 56 88 86 01 52 62 10 24 32 05 60 65 53 28 57 99 +03 50 03 52 07 73 49 92 66 80 01 46 08 67 25 36 73 93 07 42 25 53 13 96 76 83 87 90 54 89 78 22 78 91 73 51 69 09 79 94 83 53 09 40 69 62 10 79 49 47 03 81 30 +71 54 73 33 51 76 59 54 79 37 56 45 84 17 62 21 98 69 41 95 65 24 39 37 62 03 24 48 54 64 46 82 71 78 33 67 09 16 96 68 52 74 79 68 32 21 13 78 96 60 09 69 20 36 +73 26 21 44 46 38 17 83 65 98 07 23 52 46 61 97 33 13 60 31 70 15 36 77 31 58 56 93 75 68 21 36 69 53 90 75 25 82 39 50 65 94 29 30 11 33 11 13 96 02 56 47 07 49 02 +76 46 73 30 10 20 60 70 14 56 34 26 37 39 48 24 55 76 84 91 39 86 95 61 50 14 53 93 64 67 37 31 10 84 42 70 48 20 10 72 60 61 84 79 69 65 99 73 89 25 85 48 92 56 97 16 +03 14 80 27 22 30 44 27 67 75 79 32 51 54 81 29 65 14 19 04 13 82 04 91 43 40 12 52 29 99 07 76 60 25 01 07 61 71 37 92 40 47 99 66 57 01 43 44 22 40 53 53 09 69 26 81 07 +49 80 56 90 93 87 47 13 75 28 87 23 72 79 32 18 27 20 28 10 37 59 21 18 70 04 79 96 03 31 45 71 81 06 14 18 17 05 31 50 92 79 23 47 09 39 47 91 43 54 69 47 42 95 62 46 32 85 +37 18 62 85 87 28 64 05 77 51 47 26 30 65 05 70 65 75 59 80 42 52 25 20 44 10 92 17 71 95 52 14 77 13 24 55 11 65 26 91 01 30 63 15 49 48 41 17 67 47 03 68 20 90 98 32 04 40 68 +90 51 58 60 06 55 23 68 05 19 76 94 82 36 96 43 38 90 87 28 33 83 05 17 70 83 96 93 06 04 78 47 80 06 23 84 75 23 87 72 99 14 50 98 92 38 90 64 61 58 76 94 36 66 87 80 51 35 61 38 +57 95 64 06 53 36 82 51 40 33 47 14 07 98 78 65 39 58 53 06 50 53 04 69 40 68 36 69 75 78 75 60 03 32 39 24 74 47 26 90 13 40 44 71 90 76 51 24 36 50 25 45 70 80 61 80 61 43 90 64 11 +18 29 86 56 68 42 79 10 42 44 30 12 96 18 23 18 52 59 02 99 67 46 60 86 43 38 55 17 44 93 42 21 55 14 47 34 55 16 49 24 23 29 96 51 55 10 46 53 27 92 27 46 63 57 30 65 43 27 21 20 24 83 +81 72 93 19 69 52 48 01 13 83 92 69 20 48 69 59 20 62 05 42 28 89 90 99 32 72 84 17 08 87 36 03 60 31 36 36 81 26 97 36 48 54 56 56 27 16 91 08 23 11 87 99 33 47 02 14 44 73 70 99 43 35 33 +90 56 61 86 56 12 70 59 63 32 01 15 81 47 71 76 95 32 65 80 54 70 34 51 40 45 33 04 64 55 78 68 88 47 31 47 68 87 03 84 23 44 89 72 35 08 31 76 63 26 90 85 96 67 65 91 19 14 17 86 04 71 32 95 +37 13 04 22 64 37 37 28 56 62 86 33 07 37 10 44 52 82 52 06 19 52 57 75 90 26 91 24 06 21 14 67 76 30 46 14 35 89 89 41 03 64 56 97 87 63 22 34 03 79 17 45 11 53 25 56 96 61 23 18 63 31 37 37 47 +77 23 26 70 72 76 77 04 28 64 71 69 14 85 96 54 95 48 06 62 99 83 86 77 97 75 71 66 30 19 57 90 33 01 60 61 14 12 90 99 32 77 56 41 18 14 87 49 10 14 90 64 18 50 21 74 14 16 88 05 45 73 82 47 74 44 +22 97 41 13 34 31 54 61 56 94 03 24 59 27 98 77 04 09 37 40 12 26 87 09 71 70 07 18 64 57 80 21 12 71 83 94 60 39 73 79 73 19 97 32 64 29 41 07 48 84 85 67 12 74 95 20 24 52 41 67 56 61 29 93 35 72 69 +72 23 63 66 01 11 07 30 52 56 95 16 65 26 83 90 50 74 60 18 16 48 43 77 37 11 99 98 30 94 91 26 62 73 45 12 87 73 47 27 01 88 66 99 21 41 95 80 02 53 23 32 61 48 32 43 43 83 14 66 95 91 19 81 80 67 25 88 +08 62 32 18 92 14 83 71 37 96 11 83 39 99 05 16 23 27 10 67 02 25 44 11 55 31 46 64 41 56 44 74 26 81 51 31 45 85 87 09 81 95 22 28 76 69 46 48 64 87 67 76 27 89 31 11 74 16 62 03 60 94 42 47 09 34 94 93 72 +56 18 90 18 42 17 42 32 14 86 06 53 33 95 99 35 29 15 44 20 49 59 25 54 34 59 84 21 23 54 35 90 78 16 93 13 37 88 54 19 86 67 68 55 66 84 65 42 98 37 87 56 33 28 58 38 28 38 66 27 52 21 81 15 08 22 97 32 85 27 +91 53 40 28 13 34 91 25 01 63 50 37 22 49 71 58 32 28 30 18 68 94 23 83 63 62 94 76 80 41 90 22 82 52 29 12 18 56 10 08 35 14 37 57 23 65 67 40 72 39 93 39 70 89 40 34 07 46 94 22 20 05 53 64 56 30 05 56 61 88 27 +23 95 11 12 37 69 68 24 66 10 87 70 43 50 75 07 62 41 83 58 95 93 89 79 45 39 02 22 05 22 95 43 62 11 68 29 17 40 26 44 25 71 87 16 70 85 19 25 59 94 90 41 41 80 61 70 55 60 84 33 95 76 42 63 15 09 03 40 38 12 03 32 +09 84 56 80 61 55 85 97 16 94 82 94 98 57 84 30 84 48 93 90 71 05 95 90 73 17 30 98 40 64 65 89 07 79 09 19 56 36 42 30 23 69 73 72 07 05 27 61 24 31 43 48 71 84 21 28 26 65 65 59 65 74 77 20 10 81 61 84 95 08 52 23 70 +47 81 28 09 98 51 67 64 35 51 59 36 92 82 77 65 80 24 72 53 22 07 27 10 21 28 30 22 48 82 80 48 56 20 14 43 18 25 50 95 90 31 77 08 09 48 44 80 90 22 93 45 82 17 13 96 25 26 08 73 34 99 06 49 24 06 83 51 40 14 15 10 25 01 +54 25 10 81 30 64 24 74 75 80 36 75 82 60 22 69 72 91 45 67 03 62 79 54 89 74 44 83 64 96 66 73 44 30 74 50 37 05 09 97 70 01 60 46 37 91 39 75 75 18 58 52 72 78 51 81 86 52 08 97 01 46 43 66 98 62 81 18 70 93 73 08 32 46 34 +96 80 82 07 59 71 92 53 19 20 88 66 03 26 26 10 24 27 50 82 94 73 63 08 51 33 22 45 19 13 58 33 90 15 22 50 36 13 55 06 35 47 82 52 33 61 36 27 28 46 98 14 73 20 73 32 16 26 80 53 47 66 76 38 94 45 02 01 22 52 47 96 64 58 52 39 +88 46 23 39 74 63 81 64 20 90 33 33 76 55 58 26 10 46 42 26 74 74 12 83 32 43 09 02 73 55 86 54 85 34 28 23 29 79 91 62 47 41 82 87 99 22 48 90 20 05 96 75 95 04 43 28 81 39 81 01 28 42 78 25 39 77 90 57 58 98 17 36 73 22 63 74 51 +29 39 74 94 95 78 64 24 38 86 63 87 93 06 70 92 22 16 80 64 29 52 20 27 23 50 14 13 87 15 72 96 81 22 08 49 72 30 70 24 79 31 16 64 59 21 89 34 96 91 48 76 43 53 88 01 57 80 23 81 90 79 58 01 80 87 17 99 86 90 72 63 32 69 14 28 88 69 +37 17 71 95 56 93 71 35 43 45 04 98 92 94 84 96 11 30 31 27 31 60 92 03 48 05 98 91 86 94 35 90 90 08 48 19 33 28 68 37 59 26 65 96 50 68 22 07 09 49 34 31 77 49 43 06 75 17 81 87 61 79 52 26 27 72 29 50 07 98 86 01 17 10 46 64 24 18 56 +51 30 25 94 88 85 79 91 40 33 63 84 49 67 98 92 15 26 75 19 82 05 18 78 65 93 61 48 91 43 59 41 70 51 22 15 92 81 67 91 46 98 11 11 65 31 66 10 98 65 83 21 05 56 05 98 73 67 46 74 69 34 08 30 05 52 07 98 32 95 30 94 65 50 24 63 28 81 99 57 +19 23 61 36 09 89 71 98 65 17 30 29 89 26 79 74 94 11 44 48 97 54 81 55 39 66 69 45 28 47 13 86 15 76 74 70 84 32 36 33 79 20 78 14 41 47 89 28 81 05 99 66 81 86 38 26 06 25 13 60 54 55 23 53 27 05 89 25 23 11 13 54 59 54 56 34 16 24 53 44 06 +13 40 57 72 21 15 60 08 04 19 11 98 34 45 09 97 86 71 03 15 56 19 15 44 97 31 90 04 87 87 76 08 12 30 24 62 84 28 12 85 82 53 99 52 13 94 06 65 97 86 09 50 94 68 69 74 30 67 87 94 63 07 78 27 80 36 69 41 06 92 32 78 37 82 30 05 18 87 99 72 19 99 +44 20 55 77 69 91 27 31 28 81 80 27 02 07 97 23 95 98 12 25 75 29 47 71 07 47 78 39 41 59 27 76 13 15 66 61 68 35 69 86 16 53 67 63 99 85 41 56 08 28 33 40 94 76 90 85 31 70 24 65 84 65 99 82 19 25 54 37 21 46 33 02 52 99 51 33 26 04 87 02 08 18 96 +54 42 61 45 91 06 64 79 80 82 32 16 83 63 42 49 19 78 65 97 40 42 14 61 49 34 04 18 25 98 59 30 82 72 26 88 54 36 21 75 03 88 99 53 46 51 55 78 22 94 34 40 68 87 84 25 30 76 25 08 92 84 42 61 40 38 09 99 40 23 29 39 46 55 10 90 35 84 56 70 63 23 91 39 +52 92 03 71 89 07 09 37 68 66 58 20 44 92 51 56 13 71 79 99 26 37 02 06 16 67 36 52 58 16 79 73 56 60 59 27 44 77 94 82 20 50 98 33 09 87 94 37 40 83 64 83 58 85 17 76 53 02 83 52 22 27 39 20 48 92 45 21 09 42 24 23 12 37 52 28 50 78 79 20 86 62 73 20 59 +54 96 80 15 91 90 99 70 10 09 58 90 93 50 81 99 54 38 36 10 30 11 35 84 16 45 82 18 11 97 36 43 96 79 97 65 40 48 23 19 17 31 64 52 65 65 37 32 65 76 99 79 34 65 79 27 55 33 03 01 33 27 61 28 66 08 04 70 49 46 48 83 01 45 19 96 13 81 14 21 31 79 93 85 50 05 +92 92 48 84 59 98 31 53 23 27 15 22 79 95 24 76 05 79 16 93 97 89 38 89 42 83 02 88 94 95 82 21 01 97 48 39 31 78 09 65 50 56 97 61 01 07 65 27 21 23 14 15 80 97 44 78 49 35 33 45 81 74 34 05 31 57 09 38 94 07 69 54 69 32 65 68 46 68 78 90 24 28 49 51 45 86 35 +41 63 89 76 87 31 86 09 46 14 87 82 22 29 47 16 13 10 70 72 82 95 48 64 58 43 13 75 42 69 21 12 67 13 64 85 58 23 98 09 37 76 05 22 31 12 66 50 29 99 86 72 45 25 10 28 19 06 90 43 29 31 67 79 46 25 74 14 97 35 76 37 65 46 23 82 06 22 30 76 93 66 94 17 96 13 20 72 +63 40 78 08 52 09 90 41 70 28 36 14 46 44 85 96 24 52 58 15 87 37 05 98 99 39 13 61 76 38 44 99 83 74 90 22 53 80 56 98 30 51 63 39 44 30 91 91 04 22 27 73 17 35 53 18 35 45 54 56 27 78 48 13 69 36 44 38 71 25 30 56 15 22 73 43 32 69 59 25 93 83 45 11 34 94 44 39 92 +12 36 56 88 13 96 16 12 55 54 11 47 19 78 17 17 68 81 77 51 42 55 99 85 66 27 81 79 93 42 65 61 69 74 14 01 18 56 12 01 58 37 91 22 42 66 83 25 19 04 96 41 25 45 18 69 96 88 36 93 10 12 98 32 44 83 83 04 72 91 04 27 73 07 34 37 71 60 59 31 01 54 54 44 96 93 83 36 04 45 +30 18 22 20 42 96 65 79 17 41 55 69 94 81 29 80 91 31 85 25 47 26 43 49 02 99 34 67 99 76 16 14 15 93 08 32 99 44 61 77 67 50 43 55 87 55 53 72 17 46 62 25 50 99 73 05 93 48 17 31 70 80 59 09 44 59 45 13 74 66 58 94 87 73 16 14 85 38 74 99 64 23 79 28 71 42 20 37 82 31 23 +51 96 39 65 46 71 56 13 29 68 53 86 45 33 51 49 12 91 21 21 76 85 02 17 98 15 46 12 60 21 88 30 92 83 44 59 42 50 27 88 46 86 94 73 45 54 23 24 14 10 94 21 20 34 23 51 04 83 99 75 90 63 60 16 22 33 83 70 11 32 10 50 29 30 83 46 11 05 31 17 86 42 49 01 44 63 28 60 07 78 95 40 +44 61 89 59 04 49 51 27 69 71 46 76 44 04 09 34 56 39 15 06 94 91 75 90 65 27 56 23 74 06 23 33 36 69 14 39 05 34 35 57 33 22 76 46 56 10 61 65 98 09 16 69 04 62 65 18 99 76 49 18 72 66 73 83 82 40 76 31 89 91 27 88 17 35 41 35 32 51 32 67 52 68 74 85 80 57 07 11 62 66 47 22 67 +65 37 19 97 26 17 16 24 24 17 50 37 64 82 24 36 32 11 68 34 69 31 32 89 79 93 96 68 49 90 14 23 04 04 67 99 81 74 70 74 36 96 68 09 64 39 88 35 54 89 96 58 66 27 88 97 32 14 06 35 78 20 71 06 85 66 57 02 58 91 72 05 29 56 73 48 86 52 09 93 22 57 79 42 12 01 31 68 17 59 63 76 07 77 +73 81 14 13 17 20 11 09 01 83 08 85 91 70 84 63 62 77 37 07 47 01 59 95 39 69 39 21 99 09 87 02 97 16 92 36 74 71 90 66 33 73 73 75 52 91 11 12 26 53 05 26 26 48 61 50 90 65 01 87 42 47 74 35 22 73 24 26 56 70 52 05 48 41 31 18 83 27 21 39 80 85 26 08 44 02 71 07 63 22 05 52 19 08 20 +17 25 21 11 72 93 33 49 64 23 53 82 03 13 91 65 85 02 40 05 42 31 77 42 05 36 06 54 04 58 07 76 87 83 25 57 66 12 74 33 85 37 74 32 20 69 03 97 91 68 82 44 19 14 89 28 85 85 80 53 34 87 58 98 88 78 48 65 98 40 11 57 10 67 70 81 60 79 74 72 97 59 79 47 30 20 54 80 89 91 14 05 33 36 79 39 +60 85 59 39 60 07 57 76 77 92 06 35 15 72 23 41 45 52 95 18 64 79 86 53 56 31 69 11 91 31 84 50 44 82 22 81 41 40 30 42 30 91 48 94 74 76 64 58 74 25 96 57 14 19 03 99 28 83 15 75 99 01 89 85 79 50 03 95 32 67 44 08 07 41 62 64 29 20 14 76 26 55 48 71 69 66 19 72 44 25 14 01 48 74 12 98 07 +64 66 84 24 18 16 27 48 20 14 47 69 30 86 48 40 23 16 61 21 51 50 26 47 35 33 91 28 78 64 43 68 04 79 51 08 19 60 52 95 06 68 46 86 35 97 27 58 04 65 30 58 99 12 12 75 91 39 50 31 42 64 70 04 46 07 98 73 98 93 37 89 77 91 64 71 64 65 66 21 78 62 81 74 42 20 83 70 73 95 78 45 92 27 34 53 71 15 +30 11 85 31 34 71 13 48 05 14 44 03 19 67 23 73 19 57 06 90 94 72 57 69 81 62 59 68 88 57 55 69 49 13 07 87 97 80 89 05 71 05 05 26 38 40 16 62 45 99 18 38 98 24 21 26 62 74 69 04 85 57 77 35 58 67 91 79 79 57 86 28 66 34 72 51 76 78 36 95 63 90 08 78 47 63 45 31 22 70 52 48 79 94 15 77 61 67 68 +23 33 44 81 80 92 93 75 94 88 23 61 39 76 22 03 28 94 32 06 49 65 41 34 18 23 08 47 62 60 03 63 33 13 80 52 31 54 73 43 70 26 16 69 57 87 83 31 03 93 70 81 47 95 77 44 29 68 39 51 56 59 63 07 25 70 07 77 43 53 64 03 94 42 95 39 18 01 66 21 16 97 20 50 90 16 70 10 95 69 29 06 25 61 41 26 15 59 63 35 diff --git a/Python/p018.py b/Python/p018.py index c0d325f..b30017d 100644 --- a/Python/p018.py +++ b/Python/p018.py @@ -54,7 +54,7 @@ def main(): for i in range(l): triang[i] = list(map(int, triang[i])) -# Use function implemented in projecteuler.c to find the maximum path. +# Use the function implemented in projecteuler.c to find the maximum path. max_ = find_max_path(triang, 15) end = default_timer() diff --git a/Python/p049.py b/Python/p049.py index 71576bd..a7bdb78 100644 --- a/Python/p049.py +++ b/Python/p049.py @@ -13,24 +13,6 @@ from numpy import zeros from timeit import default_timer from projecteuler import sieve -def check_digits(a, b): - digits1 = zeros(10, int) - digits2 = zeros(10, int) - - while a > 0: - digits1[a%10] = digits1[a%10] + 1 - a = a // 10 - - while b > 0: - digits2[b%10] = digits2[b%10] + 1 - b = b // 10 - - for i in range(10): - if digits1[i] != digits2[i]: - return False - - return True - def main(): start = default_timer() @@ -51,7 +33,8 @@ def main(): # If i, i+j and i+2*j are all primes and they have # all the same digits, the result has been found. if i + 2 * j < N and primes[i+j] == 1 and primes[i+2*j] == 1 and\ - check_digits(i, i+j) and check_digits(i, i+2*j): + ''.join(sorted(str(i))) == ''.join(sorted(str(i+j))) and\ + ''.join(sorted(str(i))) == ''.join(sorted(str(i+2*j))): found = 1 break if(found): diff --git a/Python/p052.py b/Python/p052.py index 6a8b443..f51d063 100644 --- a/Python/p052.py +++ b/Python/p052.py @@ -8,27 +8,6 @@ from numpy import zeros from timeit import default_timer -def have_same_digits(a, b): - digits1 = zeros(10, int) - digits2 = zeros(10, int) - -# Get digits of a. - while a > 0: - digits1[a%10] = digits1[a%10] + 1 - a = a // 10 - -# Get digits of b. - while b > 0: - digits2[b%10] = digits2[b%10] + 1 - b = b // 10 - -# If they're not the same, return 0. - for i in range(10): - if digits1[i] != digits2[i]: - return 0 - - return 1 - def main(): start = default_timer() @@ -36,8 +15,11 @@ def main(): # Brute force approach, try every integer number until the desired one is found. while True: - if have_same_digits(i, 2*i) and have_same_digits(i, 3*i) and have_same_digits(i, 4*i) and\ - have_same_digits(i, 5*i) and have_same_digits(i, 6*i): + if ''.join(sorted(str(i))) == ''.join(sorted(str(2*i))) and\ + ''.join(sorted(str(i))) == ''.join(sorted(str(3*i))) and\ + ''.join(sorted(str(i))) == ''.join(sorted(str(4*i))) and\ + ''.join(sorted(str(i))) == ''.join(sorted(str(5*i))) and\ + ''.join(sorted(str(i))) == ''.join(sorted(str(6*i))): break i = i + 1 diff --git a/Python/p055.py b/Python/p055.py index 6161cb2..501ecf3 100644 --- a/Python/p055.py +++ b/Python/p055.py @@ -44,11 +44,11 @@ def is_lychrel(n): # If the sum is palindrome, the number is not a Lychrel number. if is_palindrome(tmp, 10): - return 0 + return False n = tmp - return 1 + return True def main(): start = default_timer() diff --git a/Python/p064.py b/Python/p064.py index e02fbda..159b857 100644 --- a/Python/p064.py +++ b/Python/p064.py @@ -45,16 +45,16 @@ from math import floor, sqrt from timeit import default_timer -from projecteuler import period_cf +from projecteuler import build_sqrt_cont_fraction def is_square(n): p = sqrt(n) m = int(p) if p == m: - return 1 + return True else: - return 0 + return False def main(): start = default_timer() @@ -64,8 +64,12 @@ def main(): for i in range(2, 10000): # Perfect squares are obviously not represented as continued fractions. # For all other numbers, calculate their period and check if it's odd. - if not is_square(i) and period_cf(i) % 2 != 0: - count = count + 1 + if not is_square(i): +# period_cf(i) % 2 != 0: + fraction, period = build_sqrt_cont_fraction(i, 300) + + if period % 2 != 0: + count = count + 1 end = default_timer() diff --git a/Python/p066.py b/Python/p066.py new file mode 100644 index 0000000..4187fd5 --- /dev/null +++ b/Python/p066.py @@ -0,0 +1,60 @@ +#!/usr/bin/python + +# Consider quadratic Diophantine equations of the form: +# +# x^2 – Dy^2 = 1 +# +# For example, when D=13, the minimal solution in x is 649^2 – 13×180^2 = 1. +# +# It can be assumed that there are no solutions in positive integers when D is square. +# +# By finding minimal solutions in x for D = {2, 3, 5, 6, 7}, we obtain the following: +# +# 3^2 – 2×2^2 = 1 +# 2^2 – 3×1^2 = 1 +# 9^2 – 5×4^2 = 1 +# 5^2 – 6×2^2 = 1 +# 8^2 – 7×3^2 = 1 +# +# Hence, by considering minimal solutions in x for D ≤ 7, the largest x is obtained when D=5. +# +# Find the value of D ≤ 1000 in minimal solutions of x for which the largest value of x is obtained. + +from math import sqrt + +from timeit import default_timer +from projecteuler import pell_eq + +def is_square(n): + p = sqrt(n) + m = int(p) + + if p == m: + return True + else: + return False + +def main(): + start = default_timer() + + max_ = 0 + max_d = -1 + + for i in range(2, 1001): + if not is_square(i): +# Solve the Diophantine equation x^2-D*y^2=1 (Pell equation) + x = pell_eq(i) + + if x > max_: + max_ = x + max_d = i + + end = default_timer() + + print('Project Euler, Problem 66') + print('Answer: {}'.format(max_d)) + + print('Elapsed time: {:.9f} seconds'.format(end - start)) + +if __name__ == '__main__': + main() diff --git a/Python/p067.py b/Python/p067.py new file mode 100644 index 0000000..e8dfe60 --- /dev/null +++ b/Python/p067.py @@ -0,0 +1,53 @@ +#!/usr/bin/python3 + +# By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23. +# +# 3 +# 7 4 +# 2 4 6 +# 8 5 9 3 +# +# That is, 3 + 7 + 4 + 9 = 23. +# Find the maximum total from top to bottom in triangle.txt (right click and 'Save Link/Target As...'), a 15K text file containing a triangle +# with one-hundred rows. +# +# NOTE: This is a much more difficult version of Problem 18. It is not possible to try every route to solve this problem, as there are 299 altogether! +# If you could check one trillion (1012) routes every second it would take over twenty billion years to check them all. +# There is an efficient algorithm to solve it. ;o) + +from timeit import default_timer +from projecteuler import find_max_path + +def main(): + start = default_timer() + + try: + fp = open('triangle.txt', 'r') + except: + print('Error while opening file {}'.format('triangle.txt')) + exit(1) + + triang = list() + + for line in fp: + triang.append(line.strip('\n').split()) + + fp.close() + + l = len(triang) + + for i in range(l): + triang[i] = list(map(int, triang[i])) + +# Use the function implemented in projecteuler.c to find the maximum path. + max_ = find_max_path(triang, 100) + + end = default_timer() + + print('Project Euler, Problem 67') + print('Answer: {}'.format(max_)) + + print('Elapsed time: {:.9f} seconds'.format(end - start)) + +if __name__ == '__main__': + main() diff --git a/Python/p068.py b/Python/p068.py new file mode 100644 index 0000000..c121d12 --- /dev/null +++ b/Python/p068.py @@ -0,0 +1,137 @@ +#!/usr/bin/python3 + +# Consider the following "magic" 3-gon ring, filled with the numbers 1 to 6, and each line adding to nine. +# +# 4 +# \ +# \ +# 3 +# / \ +# / \ +# 1------2------6 +# / +# / +# 5 +# +# Working clockwise, and starting from the group of three with the numerically lowest external node (4,3,2 in this example), +# each solution can be described uniquely. For example, the above solution can be described by the set: 4,3,2; 6,2,1; 5,1,3. +# +# It is possible to complete the ring with four different totals: 9, 10, 11, and 12. There are eight solutions in total. +# +# Total Solution Set +# 9 4,2,3; 5,3,1; 6,1,2 +# 9 4,3,2; 6,2,1; 5,1,3 +# 10 2,3,5; 4,5,1; 6,1,3 +# 10 2,5,3; 6,3,1; 4,1,5 +# 11 1,4,6; 3,6,2; 5,2,4 +# 11 1,6,4; 5,4,2; 3,2,6 +# 12 1,5,6; 2,6,4; 3,4,5 +# 12 1,6,5; 3,5,4; 2,4,6 +# +# By concatenating each group it is possible to form 9-digit strings; the maximum string for a 3-gon ring is 432621513. +# +# Using the numbers 1 to 10, and depending on arrangements, it is possible to form 16- and 17-digit strings. What is the maximum 16-digit string +# for a "magic" 5-gon ring? +# +# O +# \ +# O +# / \ O +# / \ / +# O O +# / \ / +# O O--O---O +# \ +# O +# + +from itertools import permutations + +from timeit import default_timer + +# Function to evaluate the ring. The ring is represented as a vector of 2*n elements, +# the first n elements represent the external nodes of the ring, the next n elements +# represent the internal ring. +def eval_ring(ring, n): + for i in range(1, n): +# We need to start from the lowest external node, so if +# the first element in the vector is not the lowest of +# the first n elements (the external elements), the configuration +# is not a valid one. + if ring[i] < ring[0]: + return None + + res = [0] * 3 * n + +# Each group of three must have the same value. + magic_val = ring[0] + ring[n] + ring[n+1] + + j = 0 + + for i in range(n): +# We need to find the maximum 16-digit string, this is +# possible only if the element "10" is used only once, +# i.e. if it's one of the external nodes. + if ring[n+i] == 10 or ring[n+(i+1)%n] == 10: + return None + +# Check that the value of the current three-element group +# is the "magic" value. + val = ring[i] + ring[n+i] + ring[n+(i+1)%n] + + if val != magic_val : + return None + +# Save the current element group in the result string. + res[j] = ring[i] + res[j+1] = ring[n+i] + res[j+2] = ring[n+(i+1)%n] + + j = j + 3 + + return res + +def list_to_int(l): + if l == None: + return 0 + + res = 0 + k = 0 + + for i in reversed(l): + res = res + i * 10 ** k + + if i >= 10: + k = k + 2 + else: + k = k + 1 + + return res + +def main(): + start = default_timer() + +# Generate all possible permutations, for each one check if +# it's a possible solution for the ring and save the maximum + rings = list(permutations(list(range(1, 11)))) + max_ = 0 + n = None + + for ring in rings: + eval_ = eval_ring(ring, 5); + +# Convert the list into an integer number. + n = list_to_int(eval_) + + if n > max_: + max_ = n + + end = default_timer() + + print('Project Euler, Problem 68') + print('Answer: {}'.format(max_)) + + print('Elapsed time: {:.9f} seconds'.format(end - start)) + +if __name__ == '__main__': + main() diff --git a/Python/p069.py b/Python/p069.py new file mode 100644 index 0000000..49df6ad --- /dev/null +++ b/Python/p069.py @@ -0,0 +1,55 @@ +#!/usr/bin/python3 + +# 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. +# +# n Relatively Prime φ(n) n/φ(n) +# 2 1 1 2 +# 3 1,2 2 1.5 +# 4 1,3 2 2 +# 5 1,2,3,4 4 1.25 +# 6 1,5 2 3 +# 7 1,2,3,4,5,6 6 1.1666... +# 8 1,3,5,7 4 2 +# 9 1,2,4,5,7,8 6 1.5 +# 10 1,3,7,9 4 2.5 +# +# 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. + +from timeit import default_timer +from projecteuler import is_prime + +def main(): + start = default_timer() + + N = 1000000 + + i = 1 + res = 1 + +# Using Euler's formula, phi(n)=n*prod(1-1/p), where p are the distinct +# primes that divide n. So n/phi(n)=1/prod(1-1/p). To find the maximum +# value of this function, the denominator must be minimized. This happens +# when n has the most distinct small prime factor, i.e. to find the solution +# we need to multiply the smallest consecutive primes until the result is +# larger than 1000000. + while res < N: + i = i + 1 + + if is_prime(i): + res = res * i + +# We need the previous value, because we want i<1000000 + res = res // i + + end = default_timer() + + print('Project Euler, Problem 69') + print('Answer: {}'.format(res)) + + print('Elapsed time: {:.9f} seconds'.format(end - start)) + +if __name__ == '__main__': + main() diff --git a/Python/p070.py b/Python/p070.py new file mode 100644 index 0000000..d00bdd8 --- /dev/null +++ b/Python/p070.py @@ -0,0 +1,51 @@ +#!/usr/bin/python3 + +# Euler's Totient function, φ(n) [sometimes called the phi function], is used to determine the number of positive numbers +# less than or equal to 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. +# The number 1 is considered to be relatively prime to every positive number, so φ(1)=1. +# +# Interestingly, φ(87109)=79180, and it can be seen that 87109 is a permutation of 79180. +# +# Find the value of n, 1 < n < 10^7, for which φ(n) is a permutation of n and the ratio n/φ(n) produces a minimum. + +from numpy import zeros + +from timeit import default_timer +from projecteuler import sieve, is_semiprime, phi_semiprime + +def main(): + start = default_timer() + + N = 10000000 + n = -1 + min_ = float('inf') + semi_p = False + + primes = sieve(N) + + for i in range(2, N): +# When n is prime, phi(n)=(n-1), so to minimize n/phi(n) we should +# use n prime. But n-1 can't be a permutation of n. The second best +# bet is to use semiprimes. For a semiprime n=p*q, phi(n)=(p-1)(q-1). +# So we check if a number is semiprime, if yes calculate phi, finally +# check if phi(n) is a permutation of n and update the minimum if it's +# smaller. + semi_p, a, b = is_semiprime(i, primes) + + if semi_p == True: + p = phi_semiprime(i, a, b) + + if ''.join(sorted(str(p))) == ''.join(sorted(str(i))) and i / p < min_: + n = i + min_ = i / p + + end = default_timer() + + print('Project Euler, Problem 70') + print('Answer: {}'.format(n)) + + print('Elapsed time: {:.9f} seconds'.format(end - start)) + +if __name__ == '__main__': + main() diff --git a/Python/projecteuler.py b/Python/projecteuler.py index 56e8449..9b9e297 100644 --- a/Python/projecteuler.py +++ b/Python/projecteuler.py @@ -190,24 +190,137 @@ def is_pentagonal(n): # d_(n+1)=(S-m_(n+1)^2)/d_n # a_(n+1)=floor((sqrt(S)+m_(n+1))/d_(n+1))=floor((a_0+m_(n+1))/d_(n+1)) # if a_i=2*a_0, the algorithm ends. -def period_cf(n): +def build_sqrt_cont_fraction(i, l): mn = 0 dn = 1 count = 0 - a0 = floor(sqrt(n)) + fraction = [0] * l + + j = 0 + a0 = floor(sqrt(i)) an = a0 + fraction[j] = an + j = j + 1 while True: mn1 = dn * an - mn - dn1 = (n - mn1 * mn1) // dn + dn1 = (i - mn1 * mn1)/ dn an1 = floor((a0+mn1)/dn1) mn = mn1 dn = dn1 an = an1 count = count + 1 + fraction[j] = an + j = j + 1 if an == 2 * a0: break - return count + fraction[j] = -1 + + return fraction, count + +# Function to solve the Diophantine equation in the form x^2-Dy^2=1 +# (Pell equation) using continued fractions. + +def pell_eq(d): +# Find the continued fraction for sqrt(d). + fraction, period = build_sqrt_cont_fraction(d, 100) + +# Calculate the first convergent of the continued fraction. + n1 = 0 + n2 = 1 + d1 = 1 + d2 = 0 + + j = 0 + n3 = fraction[j] * n2 + n1 + d3 = fraction[j] * d2 + d1 + j = j + 1 + +# Check if x=n, y=d solve the equation x^2-Dy^2=1. + sol = n3 * n3 - d * d3 * d3 + + if sol == 1: + return n3 + +# Until a solution is found, calculate the next convergent +# and check if x=n and y=d solve the equation. + while True: + n1 = n2 + n2 = n3 + d1 = d2 + d2 = d3 + n3 = fraction[j] * n2 + n1 + d3 = fraction[j] * d2 + d1 + + sol = n3 * n3 - d * d3 * d3 + + if sol == 1: + return n3 + + j = j + 1 + + if fraction[j] == -1: + j = 1 + +# Function to check if a number is semiprime. Parameters include +# pointers to p and q to return the factors values and a list of +# primes. +def is_semiprime(n, primes): +# If n is prime, it's not semiprime. + if primes[n] == 1: + return False, -1, -1 + +# Check if n is semiprime and one of the factors is 2. + if n % 2 == 0: + if primes[n//2] == 1: + p = 2 + q = n // 2 + return True, p, q + else: + return False, -1, -1 +# Check if n is semiprime and one of the factors is 3. + elif n % 3 == 0: + if primes[n//3] == 1: + p = 3 + q = n // 3 + return True, p, q + else: + return False, -1, -1 + +# Any number can have only one prime factor greater than its +# square root, so we can stop checking at this point. + limit = floor(sqrt(n)) + 1 + +# 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 if the number is semiprime with using +# that factor. + for i in range(5, limit, 6): + if primes[i] == 1 and n % i == 0: + if primes[n//i] == 1: + p = i + q = n // i + return True, p, q + else: + return False, -1, -1 + elif primes[i+2] == 1 and n % (i + 2) == 0: + if primes[n//(i+2)] == 1: + p = i + 2 + q = n // (i + 2) + return True, p, q + else: + return False, -1, -1 + + return False, -1, -1 + +# If n=pq is semiprime, phi(n)=(p-1)(q-1)=pq-p-q+1=n-(p+4)+1 +# if p!=q. If p=q (n is a square), phi(n)=n-p. +def phi_semiprime(n, p, q): + if p == q: + return n - p + else: + return n - (p + q) + 1 diff --git a/Python/triangle.txt b/Python/triangle.txt new file mode 100644 index 0000000..00aa2bc --- /dev/null +++ b/Python/triangle.txt @@ -0,0 +1,100 @@ +59 +73 41 +52 40 09 +26 53 06 34 +10 51 87 86 81 +61 95 66 57 25 68 +90 81 80 38 92 67 73 +30 28 51 76 81 18 75 44 +84 14 95 87 62 81 17 78 58 +21 46 71 58 02 79 62 39 31 09 +56 34 35 53 78 31 81 18 90 93 15 +78 53 04 21 84 93 32 13 97 11 37 51 +45 03 81 79 05 18 78 86 13 30 63 99 95 +39 87 96 28 03 38 42 17 82 87 58 07 22 57 +06 17 51 17 07 93 09 07 75 97 95 78 87 08 53 +67 66 59 60 88 99 94 65 55 77 55 34 27 53 78 28 +76 40 41 04 87 16 09 42 75 69 23 97 30 60 10 79 87 +12 10 44 26 21 36 32 84 98 60 13 12 36 16 63 31 91 35 +70 39 06 05 55 27 38 48 28 22 34 35 62 62 15 14 94 89 86 +66 56 68 84 96 21 34 34 34 81 62 40 65 54 62 05 98 03 02 60 +38 89 46 37 99 54 34 53 36 14 70 26 02 90 45 13 31 61 83 73 47 +36 10 63 96 60 49 41 05 37 42 14 58 84 93 96 17 09 43 05 43 06 59 +66 57 87 57 61 28 37 51 84 73 79 15 39 95 88 87 43 39 11 86 77 74 18 +54 42 05 79 30 49 99 73 46 37 50 02 45 09 54 52 27 95 27 65 19 45 26 45 +71 39 17 78 76 29 52 90 18 99 78 19 35 62 71 19 23 65 93 85 49 33 75 09 02 +33 24 47 61 60 55 32 88 57 55 91 54 46 57 07 77 98 52 80 99 24 25 46 78 79 05 +92 09 13 55 10 67 26 78 76 82 63 49 51 31 24 68 05 57 07 54 69 21 67 43 17 63 12 +24 59 06 08 98 74 66 26 61 60 13 03 09 09 24 30 71 08 88 70 72 70 29 90 11 82 41 34 +66 82 67 04 36 60 92 77 91 85 62 49 59 61 30 90 29 94 26 41 89 04 53 22 83 41 09 74 90 +48 28 26 37 28 52 77 26 51 32 18 98 79 36 62 13 17 08 19 54 89 29 73 68 42 14 08 16 70 37 +37 60 69 70 72 71 09 59 13 60 38 13 57 36 09 30 43 89 30 39 15 02 44 73 05 73 26 63 56 86 12 +55 55 85 50 62 99 84 77 28 85 03 21 27 22 19 26 82 69 54 04 13 07 85 14 01 15 70 59 89 95 10 19 +04 09 31 92 91 38 92 86 98 75 21 05 64 42 62 84 36 20 73 42 21 23 22 51 51 79 25 45 85 53 03 43 22 +75 63 02 49 14 12 89 14 60 78 92 16 44 82 38 30 72 11 46 52 90 27 08 65 78 03 85 41 57 79 39 52 33 48 +78 27 56 56 39 13 19 43 86 72 58 95 39 07 04 34 21 98 39 15 39 84 89 69 84 46 37 57 59 35 59 50 26 15 93 +42 89 36 27 78 91 24 11 17 41 05 94 07 69 51 96 03 96 47 90 90 45 91 20 50 56 10 32 36 49 04 53 85 92 25 65 +52 09 61 30 61 97 66 21 96 92 98 90 06 34 96 60 32 69 68 33 75 84 18 31 71 50 84 63 03 03 19 11 28 42 75 45 45 +61 31 61 68 96 34 49 39 05 71 76 59 62 67 06 47 96 99 34 21 32 47 52 07 71 60 42 72 94 56 82 83 84 40 94 87 82 46 +01 20 60 14 17 38 26 78 66 81 45 95 18 51 98 81 48 16 53 88 37 52 69 95 72 93 22 34 98 20 54 27 73 61 56 63 60 34 63 +93 42 94 83 47 61 27 51 79 79 45 01 44 73 31 70 83 42 88 25 53 51 30 15 65 94 80 44 61 84 12 77 02 62 02 65 94 42 14 94 +32 73 09 67 68 29 74 98 10 19 85 48 38 31 85 67 53 93 93 77 47 67 39 72 94 53 18 43 77 40 78 32 29 59 24 06 02 83 50 60 66 +32 01 44 30 16 51 15 81 98 15 10 62 86 79 50 62 45 60 70 38 31 85 65 61 64 06 69 84 14 22 56 43 09 48 66 69 83 91 60 40 36 61 +92 48 22 99 15 95 64 43 01 16 94 02 99 19 17 69 11 58 97 56 89 31 77 45 67 96 12 73 08 20 36 47 81 44 50 64 68 85 40 81 85 52 09 +91 35 92 45 32 84 62 15 19 64 21 66 06 01 52 80 62 59 12 25 88 28 91 50 40 16 22 99 92 79 87 51 21 77 74 77 07 42 38 42 74 83 02 05 +46 19 77 66 24 18 05 32 02 84 31 99 92 58 96 72 91 36 62 99 55 29 53 42 12 37 26 58 89 50 66 19 82 75 12 48 24 87 91 85 02 07 03 76 86 +99 98 84 93 07 17 33 61 92 20 66 60 24 66 40 30 67 05 37 29 24 96 03 27 70 62 13 04 45 47 59 88 43 20 66 15 46 92 30 04 71 66 78 70 53 99 +67 60 38 06 88 04 17 72 10 99 71 07 42 25 54 05 26 64 91 50 45 71 06 30 67 48 69 82 08 56 80 67 18 46 66 63 01 20 08 80 47 07 91 16 03 79 87 +18 54 78 49 80 48 77 40 68 23 60 88 58 80 33 57 11 69 55 53 64 02 94 49 60 92 16 35 81 21 82 96 25 24 96 18 02 05 49 03 50 77 06 32 84 27 18 38 +68 01 50 04 03 21 42 94 53 24 89 05 92 26 52 36 68 11 85 01 04 42 02 45 15 06 50 04 53 73 25 74 81 88 98 21 67 84 79 97 99 20 95 04 40 46 02 58 87 +94 10 02 78 88 52 21 03 88 60 06 53 49 71 20 91 12 65 07 49 21 22 11 41 58 99 36 16 09 48 17 24 52 36 23 15 72 16 84 56 02 99 43 76 81 71 29 39 49 17 +64 39 59 84 86 16 17 66 03 09 43 06 64 18 63 29 68 06 23 07 87 14 26 35 17 12 98 41 53 64 78 18 98 27 28 84 80 67 75 62 10 11 76 90 54 10 05 54 41 39 66 +43 83 18 37 32 31 52 29 95 47 08 76 35 11 04 53 35 43 34 10 52 57 12 36 20 39 40 55 78 44 07 31 38 26 08 15 56 88 86 01 52 62 10 24 32 05 60 65 53 28 57 99 +03 50 03 52 07 73 49 92 66 80 01 46 08 67 25 36 73 93 07 42 25 53 13 96 76 83 87 90 54 89 78 22 78 91 73 51 69 09 79 94 83 53 09 40 69 62 10 79 49 47 03 81 30 +71 54 73 33 51 76 59 54 79 37 56 45 84 17 62 21 98 69 41 95 65 24 39 37 62 03 24 48 54 64 46 82 71 78 33 67 09 16 96 68 52 74 79 68 32 21 13 78 96 60 09 69 20 36 +73 26 21 44 46 38 17 83 65 98 07 23 52 46 61 97 33 13 60 31 70 15 36 77 31 58 56 93 75 68 21 36 69 53 90 75 25 82 39 50 65 94 29 30 11 33 11 13 96 02 56 47 07 49 02 +76 46 73 30 10 20 60 70 14 56 34 26 37 39 48 24 55 76 84 91 39 86 95 61 50 14 53 93 64 67 37 31 10 84 42 70 48 20 10 72 60 61 84 79 69 65 99 73 89 25 85 48 92 56 97 16 +03 14 80 27 22 30 44 27 67 75 79 32 51 54 81 29 65 14 19 04 13 82 04 91 43 40 12 52 29 99 07 76 60 25 01 07 61 71 37 92 40 47 99 66 57 01 43 44 22 40 53 53 09 69 26 81 07 +49 80 56 90 93 87 47 13 75 28 87 23 72 79 32 18 27 20 28 10 37 59 21 18 70 04 79 96 03 31 45 71 81 06 14 18 17 05 31 50 92 79 23 47 09 39 47 91 43 54 69 47 42 95 62 46 32 85 +37 18 62 85 87 28 64 05 77 51 47 26 30 65 05 70 65 75 59 80 42 52 25 20 44 10 92 17 71 95 52 14 77 13 24 55 11 65 26 91 01 30 63 15 49 48 41 17 67 47 03 68 20 90 98 32 04 40 68 +90 51 58 60 06 55 23 68 05 19 76 94 82 36 96 43 38 90 87 28 33 83 05 17 70 83 96 93 06 04 78 47 80 06 23 84 75 23 87 72 99 14 50 98 92 38 90 64 61 58 76 94 36 66 87 80 51 35 61 38 +57 95 64 06 53 36 82 51 40 33 47 14 07 98 78 65 39 58 53 06 50 53 04 69 40 68 36 69 75 78 75 60 03 32 39 24 74 47 26 90 13 40 44 71 90 76 51 24 36 50 25 45 70 80 61 80 61 43 90 64 11 +18 29 86 56 68 42 79 10 42 44 30 12 96 18 23 18 52 59 02 99 67 46 60 86 43 38 55 17 44 93 42 21 55 14 47 34 55 16 49 24 23 29 96 51 55 10 46 53 27 92 27 46 63 57 30 65 43 27 21 20 24 83 +81 72 93 19 69 52 48 01 13 83 92 69 20 48 69 59 20 62 05 42 28 89 90 99 32 72 84 17 08 87 36 03 60 31 36 36 81 26 97 36 48 54 56 56 27 16 91 08 23 11 87 99 33 47 02 14 44 73 70 99 43 35 33 +90 56 61 86 56 12 70 59 63 32 01 15 81 47 71 76 95 32 65 80 54 70 34 51 40 45 33 04 64 55 78 68 88 47 31 47 68 87 03 84 23 44 89 72 35 08 31 76 63 26 90 85 96 67 65 91 19 14 17 86 04 71 32 95 +37 13 04 22 64 37 37 28 56 62 86 33 07 37 10 44 52 82 52 06 19 52 57 75 90 26 91 24 06 21 14 67 76 30 46 14 35 89 89 41 03 64 56 97 87 63 22 34 03 79 17 45 11 53 25 56 96 61 23 18 63 31 37 37 47 +77 23 26 70 72 76 77 04 28 64 71 69 14 85 96 54 95 48 06 62 99 83 86 77 97 75 71 66 30 19 57 90 33 01 60 61 14 12 90 99 32 77 56 41 18 14 87 49 10 14 90 64 18 50 21 74 14 16 88 05 45 73 82 47 74 44 +22 97 41 13 34 31 54 61 56 94 03 24 59 27 98 77 04 09 37 40 12 26 87 09 71 70 07 18 64 57 80 21 12 71 83 94 60 39 73 79 73 19 97 32 64 29 41 07 48 84 85 67 12 74 95 20 24 52 41 67 56 61 29 93 35 72 69 +72 23 63 66 01 11 07 30 52 56 95 16 65 26 83 90 50 74 60 18 16 48 43 77 37 11 99 98 30 94 91 26 62 73 45 12 87 73 47 27 01 88 66 99 21 41 95 80 02 53 23 32 61 48 32 43 43 83 14 66 95 91 19 81 80 67 25 88 +08 62 32 18 92 14 83 71 37 96 11 83 39 99 05 16 23 27 10 67 02 25 44 11 55 31 46 64 41 56 44 74 26 81 51 31 45 85 87 09 81 95 22 28 76 69 46 48 64 87 67 76 27 89 31 11 74 16 62 03 60 94 42 47 09 34 94 93 72 +56 18 90 18 42 17 42 32 14 86 06 53 33 95 99 35 29 15 44 20 49 59 25 54 34 59 84 21 23 54 35 90 78 16 93 13 37 88 54 19 86 67 68 55 66 84 65 42 98 37 87 56 33 28 58 38 28 38 66 27 52 21 81 15 08 22 97 32 85 27 +91 53 40 28 13 34 91 25 01 63 50 37 22 49 71 58 32 28 30 18 68 94 23 83 63 62 94 76 80 41 90 22 82 52 29 12 18 56 10 08 35 14 37 57 23 65 67 40 72 39 93 39 70 89 40 34 07 46 94 22 20 05 53 64 56 30 05 56 61 88 27 +23 95 11 12 37 69 68 24 66 10 87 70 43 50 75 07 62 41 83 58 95 93 89 79 45 39 02 22 05 22 95 43 62 11 68 29 17 40 26 44 25 71 87 16 70 85 19 25 59 94 90 41 41 80 61 70 55 60 84 33 95 76 42 63 15 09 03 40 38 12 03 32 +09 84 56 80 61 55 85 97 16 94 82 94 98 57 84 30 84 48 93 90 71 05 95 90 73 17 30 98 40 64 65 89 07 79 09 19 56 36 42 30 23 69 73 72 07 05 27 61 24 31 43 48 71 84 21 28 26 65 65 59 65 74 77 20 10 81 61 84 95 08 52 23 70 +47 81 28 09 98 51 67 64 35 51 59 36 92 82 77 65 80 24 72 53 22 07 27 10 21 28 30 22 48 82 80 48 56 20 14 43 18 25 50 95 90 31 77 08 09 48 44 80 90 22 93 45 82 17 13 96 25 26 08 73 34 99 06 49 24 06 83 51 40 14 15 10 25 01 +54 25 10 81 30 64 24 74 75 80 36 75 82 60 22 69 72 91 45 67 03 62 79 54 89 74 44 83 64 96 66 73 44 30 74 50 37 05 09 97 70 01 60 46 37 91 39 75 75 18 58 52 72 78 51 81 86 52 08 97 01 46 43 66 98 62 81 18 70 93 73 08 32 46 34 +96 80 82 07 59 71 92 53 19 20 88 66 03 26 26 10 24 27 50 82 94 73 63 08 51 33 22 45 19 13 58 33 90 15 22 50 36 13 55 06 35 47 82 52 33 61 36 27 28 46 98 14 73 20 73 32 16 26 80 53 47 66 76 38 94 45 02 01 22 52 47 96 64 58 52 39 +88 46 23 39 74 63 81 64 20 90 33 33 76 55 58 26 10 46 42 26 74 74 12 83 32 43 09 02 73 55 86 54 85 34 28 23 29 79 91 62 47 41 82 87 99 22 48 90 20 05 96 75 95 04 43 28 81 39 81 01 28 42 78 25 39 77 90 57 58 98 17 36 73 22 63 74 51 +29 39 74 94 95 78 64 24 38 86 63 87 93 06 70 92 22 16 80 64 29 52 20 27 23 50 14 13 87 15 72 96 81 22 08 49 72 30 70 24 79 31 16 64 59 21 89 34 96 91 48 76 43 53 88 01 57 80 23 81 90 79 58 01 80 87 17 99 86 90 72 63 32 69 14 28 88 69 +37 17 71 95 56 93 71 35 43 45 04 98 92 94 84 96 11 30 31 27 31 60 92 03 48 05 98 91 86 94 35 90 90 08 48 19 33 28 68 37 59 26 65 96 50 68 22 07 09 49 34 31 77 49 43 06 75 17 81 87 61 79 52 26 27 72 29 50 07 98 86 01 17 10 46 64 24 18 56 +51 30 25 94 88 85 79 91 40 33 63 84 49 67 98 92 15 26 75 19 82 05 18 78 65 93 61 48 91 43 59 41 70 51 22 15 92 81 67 91 46 98 11 11 65 31 66 10 98 65 83 21 05 56 05 98 73 67 46 74 69 34 08 30 05 52 07 98 32 95 30 94 65 50 24 63 28 81 99 57 +19 23 61 36 09 89 71 98 65 17 30 29 89 26 79 74 94 11 44 48 97 54 81 55 39 66 69 45 28 47 13 86 15 76 74 70 84 32 36 33 79 20 78 14 41 47 89 28 81 05 99 66 81 86 38 26 06 25 13 60 54 55 23 53 27 05 89 25 23 11 13 54 59 54 56 34 16 24 53 44 06 +13 40 57 72 21 15 60 08 04 19 11 98 34 45 09 97 86 71 03 15 56 19 15 44 97 31 90 04 87 87 76 08 12 30 24 62 84 28 12 85 82 53 99 52 13 94 06 65 97 86 09 50 94 68 69 74 30 67 87 94 63 07 78 27 80 36 69 41 06 92 32 78 37 82 30 05 18 87 99 72 19 99 +44 20 55 77 69 91 27 31 28 81 80 27 02 07 97 23 95 98 12 25 75 29 47 71 07 47 78 39 41 59 27 76 13 15 66 61 68 35 69 86 16 53 67 63 99 85 41 56 08 28 33 40 94 76 90 85 31 70 24 65 84 65 99 82 19 25 54 37 21 46 33 02 52 99 51 33 26 04 87 02 08 18 96 +54 42 61 45 91 06 64 79 80 82 32 16 83 63 42 49 19 78 65 97 40 42 14 61 49 34 04 18 25 98 59 30 82 72 26 88 54 36 21 75 03 88 99 53 46 51 55 78 22 94 34 40 68 87 84 25 30 76 25 08 92 84 42 61 40 38 09 99 40 23 29 39 46 55 10 90 35 84 56 70 63 23 91 39 +52 92 03 71 89 07 09 37 68 66 58 20 44 92 51 56 13 71 79 99 26 37 02 06 16 67 36 52 58 16 79 73 56 60 59 27 44 77 94 82 20 50 98 33 09 87 94 37 40 83 64 83 58 85 17 76 53 02 83 52 22 27 39 20 48 92 45 21 09 42 24 23 12 37 52 28 50 78 79 20 86 62 73 20 59 +54 96 80 15 91 90 99 70 10 09 58 90 93 50 81 99 54 38 36 10 30 11 35 84 16 45 82 18 11 97 36 43 96 79 97 65 40 48 23 19 17 31 64 52 65 65 37 32 65 76 99 79 34 65 79 27 55 33 03 01 33 27 61 28 66 08 04 70 49 46 48 83 01 45 19 96 13 81 14 21 31 79 93 85 50 05 +92 92 48 84 59 98 31 53 23 27 15 22 79 95 24 76 05 79 16 93 97 89 38 89 42 83 02 88 94 95 82 21 01 97 48 39 31 78 09 65 50 56 97 61 01 07 65 27 21 23 14 15 80 97 44 78 49 35 33 45 81 74 34 05 31 57 09 38 94 07 69 54 69 32 65 68 46 68 78 90 24 28 49 51 45 86 35 +41 63 89 76 87 31 86 09 46 14 87 82 22 29 47 16 13 10 70 72 82 95 48 64 58 43 13 75 42 69 21 12 67 13 64 85 58 23 98 09 37 76 05 22 31 12 66 50 29 99 86 72 45 25 10 28 19 06 90 43 29 31 67 79 46 25 74 14 97 35 76 37 65 46 23 82 06 22 30 76 93 66 94 17 96 13 20 72 +63 40 78 08 52 09 90 41 70 28 36 14 46 44 85 96 24 52 58 15 87 37 05 98 99 39 13 61 76 38 44 99 83 74 90 22 53 80 56 98 30 51 63 39 44 30 91 91 04 22 27 73 17 35 53 18 35 45 54 56 27 78 48 13 69 36 44 38 71 25 30 56 15 22 73 43 32 69 59 25 93 83 45 11 34 94 44 39 92 +12 36 56 88 13 96 16 12 55 54 11 47 19 78 17 17 68 81 77 51 42 55 99 85 66 27 81 79 93 42 65 61 69 74 14 01 18 56 12 01 58 37 91 22 42 66 83 25 19 04 96 41 25 45 18 69 96 88 36 93 10 12 98 32 44 83 83 04 72 91 04 27 73 07 34 37 71 60 59 31 01 54 54 44 96 93 83 36 04 45 +30 18 22 20 42 96 65 79 17 41 55 69 94 81 29 80 91 31 85 25 47 26 43 49 02 99 34 67 99 76 16 14 15 93 08 32 99 44 61 77 67 50 43 55 87 55 53 72 17 46 62 25 50 99 73 05 93 48 17 31 70 80 59 09 44 59 45 13 74 66 58 94 87 73 16 14 85 38 74 99 64 23 79 28 71 42 20 37 82 31 23 +51 96 39 65 46 71 56 13 29 68 53 86 45 33 51 49 12 91 21 21 76 85 02 17 98 15 46 12 60 21 88 30 92 83 44 59 42 50 27 88 46 86 94 73 45 54 23 24 14 10 94 21 20 34 23 51 04 83 99 75 90 63 60 16 22 33 83 70 11 32 10 50 29 30 83 46 11 05 31 17 86 42 49 01 44 63 28 60 07 78 95 40 +44 61 89 59 04 49 51 27 69 71 46 76 44 04 09 34 56 39 15 06 94 91 75 90 65 27 56 23 74 06 23 33 36 69 14 39 05 34 35 57 33 22 76 46 56 10 61 65 98 09 16 69 04 62 65 18 99 76 49 18 72 66 73 83 82 40 76 31 89 91 27 88 17 35 41 35 32 51 32 67 52 68 74 85 80 57 07 11 62 66 47 22 67 +65 37 19 97 26 17 16 24 24 17 50 37 64 82 24 36 32 11 68 34 69 31 32 89 79 93 96 68 49 90 14 23 04 04 67 99 81 74 70 74 36 96 68 09 64 39 88 35 54 89 96 58 66 27 88 97 32 14 06 35 78 20 71 06 85 66 57 02 58 91 72 05 29 56 73 48 86 52 09 93 22 57 79 42 12 01 31 68 17 59 63 76 07 77 +73 81 14 13 17 20 11 09 01 83 08 85 91 70 84 63 62 77 37 07 47 01 59 95 39 69 39 21 99 09 87 02 97 16 92 36 74 71 90 66 33 73 73 75 52 91 11 12 26 53 05 26 26 48 61 50 90 65 01 87 42 47 74 35 22 73 24 26 56 70 52 05 48 41 31 18 83 27 21 39 80 85 26 08 44 02 71 07 63 22 05 52 19 08 20 +17 25 21 11 72 93 33 49 64 23 53 82 03 13 91 65 85 02 40 05 42 31 77 42 05 36 06 54 04 58 07 76 87 83 25 57 66 12 74 33 85 37 74 32 20 69 03 97 91 68 82 44 19 14 89 28 85 85 80 53 34 87 58 98 88 78 48 65 98 40 11 57 10 67 70 81 60 79 74 72 97 59 79 47 30 20 54 80 89 91 14 05 33 36 79 39 +60 85 59 39 60 07 57 76 77 92 06 35 15 72 23 41 45 52 95 18 64 79 86 53 56 31 69 11 91 31 84 50 44 82 22 81 41 40 30 42 30 91 48 94 74 76 64 58 74 25 96 57 14 19 03 99 28 83 15 75 99 01 89 85 79 50 03 95 32 67 44 08 07 41 62 64 29 20 14 76 26 55 48 71 69 66 19 72 44 25 14 01 48 74 12 98 07 +64 66 84 24 18 16 27 48 20 14 47 69 30 86 48 40 23 16 61 21 51 50 26 47 35 33 91 28 78 64 43 68 04 79 51 08 19 60 52 95 06 68 46 86 35 97 27 58 04 65 30 58 99 12 12 75 91 39 50 31 42 64 70 04 46 07 98 73 98 93 37 89 77 91 64 71 64 65 66 21 78 62 81 74 42 20 83 70 73 95 78 45 92 27 34 53 71 15 +30 11 85 31 34 71 13 48 05 14 44 03 19 67 23 73 19 57 06 90 94 72 57 69 81 62 59 68 88 57 55 69 49 13 07 87 97 80 89 05 71 05 05 26 38 40 16 62 45 99 18 38 98 24 21 26 62 74 69 04 85 57 77 35 58 67 91 79 79 57 86 28 66 34 72 51 76 78 36 95 63 90 08 78 47 63 45 31 22 70 52 48 79 94 15 77 61 67 68 +23 33 44 81 80 92 93 75 94 88 23 61 39 76 22 03 28 94 32 06 49 65 41 34 18 23 08 47 62 60 03 63 33 13 80 52 31 54 73 43 70 26 16 69 57 87 83 31 03 93 70 81 47 95 77 44 29 68 39 51 56 59 63 07 25 70 07 77 43 53 64 03 94 42 95 39 18 01 66 21 16 97 20 50 90 16 70 10 95 69 29 06 25 61 41 26 15 59 63 35