diff --git a/C/p026.c b/C/p026.c index 80519f4..23754ea 100644 --- a/C/p026.c +++ b/C/p026.c @@ -57,7 +57,7 @@ int main(int argc, char **argv) /* After eliminating factors 2s and 5s, the length of the repeating cycle * of 1/d is the smallest n for which k=10^n-1/d is an integer. So we start * with k=9, then k=99, k=999 and so on until k is divisible by d. - * The number of digits of k (n) is the length of the repeating cycle.*/ + * The number of digits of k is the length of the repeating cycle.*/ while(!mpz_divisible_p(k, div)) { n++; diff --git a/C/p031.c b/C/p031.c index 41982ab..84c8d8e 100644 --- a/C/p031.c +++ b/C/p031.c @@ -1,3 +1,13 @@ +/* In England the currency is made up of pound, £, and pence, p, and there are eight coins in general circulation: + * + * 1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p). + * + * It is possible to make £2 in the following way: + * + * 1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p + * + * How many different ways can £2 be made using any number of coins?*/ + #include #include #include @@ -28,6 +38,7 @@ int main(int argc, char **argv) return 0; } +/* Simple recursive function that tries every combination.*/ int count(int value, int n, int i) { int j; diff --git a/C/p032.c b/C/p032.c index 6ace912..515f17c 100644 --- a/C/p032.c +++ b/C/p032.c @@ -1,5 +1,15 @@ +/* We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once; for example, the 5-digit number, 15234, + * is 1 through 5 pandigital. + * + * The product 7254 is unusual, as the identity, 39 × 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital. + * + * Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital. + * + * HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum.*/ + #include #include +#include #include #include "projecteuler.h" @@ -7,21 +17,23 @@ int compare(void *a, void *b); int main(int argc, char **argv) { - int a, b, i, j, k, p, p1, d, sum, n=0; - int digits[10]; + int a, b, i, j, p, sum, n = 0, num; int **products; + char num_s[10]; double elapsed; struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); - if((products = (int **)malloc(100*sizeof(int *))) == NULL) + /* Initially I used a bigger array, but printing the resulting products + * shows that 10 values are sufficient.*/ + if((products = (int **)malloc(10*sizeof(int *))) == NULL) { fprintf(stderr, "Error while allocating memory\n"); return 1; } - for(i = 0; i < 100; i++) + for(i = 0; i < 10; i++) { if((products[i] = (int *)malloc(sizeof(int))) == NULL) { @@ -30,56 +42,33 @@ int main(int argc, char **argv) } } - for(i = 2; i <= 99; i++) + /* To get a 1 to 9 pandigital concatenation of the two factors and product, + * we need to multiply a 1 digit number times a 4 digit numbers (the biggest + * one digit number 9 times the biggest 3 digit number 999 multiplied give + * 8991 and the total digit count is 8, which is not enough), or a 2 digit + * number times a 3 digit number (the smallest two different 3 digits number, + * 100 and 101, multiplied give 10100, and the total digit count is 11, which + * is too many). The outer loop starts at 2 because 1 times any number gives + * the same number, so its digit will be repeated and the result can't be + * pandigital. The nested loop starts from 1234 because it's the smallest + * 4-digit number with no repeated digits, and it ends at 4987 because it's + * the biggest number without repeated digits that multiplied by 2 gives a + * 4 digit number. */ + for(i = 2; i < 9; i++) { - for(j = 100; j <= 9999; j++) + for(j = 1234; j < 4987; j++) { - a = i; - b = j; - p = a * b; + p = i * j; + sprintf(num_s, "%d%d%d", i, j, p); - for(k = 0; k < 10; k++) + if(strlen(num_s) > 9) { - digits[k] = 0; - } - - do - { - d = a % 10; - digits[d]++; - a /= 10; - }while(a > 0); - - do - { - d = b % 10; - digits[d]++; - b /= 10; - }while(b > 0); - - p1 = p; - - do - { - d = p1 % 10; - digits[d]++; - p1 /= 10; - }while(p1 > 0); - - k = 0; - - if(digits[0] == 0) - { - for(k = 1; k < 10; k++) - { - if(digits[k] > 1 || digits[k] == 0) - { - break; - } - } + break; } - if(k == 10) + num = atoi(num_s); + + if(is_pandigital(num, 9)) { *products[n] = p; n++; @@ -87,11 +76,38 @@ int main(int argc, char **argv) } } - quick_sort((void **)products, 0, 99, compare); + /* The outer loop starts at 12 because 10 has a 0 and 11 has two 1s, so + * the result can't be pandigital. The nested loop starts at 123 because + * it's the smallest 3-digit number with no digit repetitions and ends at + * 833, because 834*12 has 5 digits.*/ + for(i = 12; i < 99; i++) + { + for(j = 123; j < 834; j++) + { + p = i * j; + sprintf(num_s, "%d%d%d", i, j, p); + + if(strlen(num_s) > 9) + { + break; + } + + num = atoi(num_s); + + if(is_pandigital(num, 9)) + { + *products[n] = p; + n++; + } + } + } + + /* Sort the found products to easily see if there are duplicates.*/ + insertion_sort((void **)products, 0, n-1, compare); sum = *products[0]; - for(i = 1; i < 100; i++) + for(i = 1; i < n; i++) { if(*products[i] != *products[i-1]) { @@ -99,7 +115,7 @@ int main(int argc, char **argv) } } - for(i = 0; i < 100; i++) + for(i = 0; i < 10; i++) { free(products[i]); } diff --git a/C/p033.c b/C/p033.c index ce8509f..59ed02d 100644 --- a/C/p033.c +++ b/C/p033.c @@ -1,3 +1,13 @@ +/* The fraction 49/98 is a curious fraction, as an inexperienced mathematician in attempting to simplify it may incorrectly believe that 49/98 = 4/8, + * which is correct, is obtained by cancelling the 9s. + * + * We shall consider fractions like, 30/50 = 3/5, to be trivial examples. + * + * There are exactly four non-trivial examples of this type of fraction, less than one in value, and containing two digits in the numerator + * and denominator. + * + * If the product of these four fractions is given in its lowest common terms, find the value of the denominator.*/ + #include #include #include @@ -5,7 +15,7 @@ int main(int argc, char **argv) { - int i, j, n, d, prod_n=1, prod_d=1, div; + int i, j, n, d, prod_n = 1, prod_d = 1, div; float f1, f2; double elapsed; struct timespec start, end; @@ -16,6 +26,8 @@ int main(int argc, char **argv) { for(j = 11; j < 100; j++) { + /* If the example is non-trivial, check if cancelling the digit that's equal + * in numerator and denominator gives the same fraction.*/ if(i % 10 && j % 10 && i != j && i % 10 == j / 10) { n = i / 10; @@ -33,6 +45,7 @@ int main(int argc, char **argv) } } + /* Find the greater common divisor of the fraction found.*/ div = gcd(prod_n, prod_d); clock_gettime(CLOCK_MONOTONIC, &end); diff --git a/C/p034.c b/C/p034.c index 6bae6bd..047f286 100644 --- a/C/p034.c +++ b/C/p034.c @@ -1,3 +1,9 @@ +/* 145 is a curious number, as 1! + 4! + 5! = 1 + 24 + 120 = 145. + * + * Find the sum of all numbers which are equal to the sum of the factorial of their digits. + * + * Note: as 1! = 1 and 2! = 2 are not sums they are not included.*/ + #include #include #include @@ -22,12 +28,14 @@ int main(int argc, char **argv) mpz_init_set_ui(factorials[i], 1); } + /* Pre-calculate factorials of each digit from 0 to 9.*/ for(i = 2; i < 10; i++) { mpz_fac_ui(factorials[i], i); } - while(mpz_cmp_ui(a, 50000) < 0) + /* 9!*7<9999999, so 9999999 is certainly un upper bound.*/ + while(mpz_cmp_ui(a, 9999999) < 0) { mpz_set(b, a); mpz_set_ui(sum_f, 0); diff --git a/C/p035.c b/C/p035.c index 8b0447c..7ab218f 100644 --- a/C/p035.c +++ b/C/p035.c @@ -1,3 +1,9 @@ +/* The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime. + * + * There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97. + * + * How many circular primes are there below one million?*/ + #include #include #include @@ -18,12 +24,14 @@ int main(int argc, char **argv) clock_gettime(CLOCK_MONOTONIC, &start); + /* Calculate all primes below one million, then check if they're circular.*/ if((primes = sieve(N)) == NULL) { fprintf(stderr, "Error! Sieve function returned NULL\n"); return 1; } + /* Starting from 101 because we already know that there are 13 circular primes below 100.*/ for(i = 101; i < 1000000; i += 2) { if(is_circular_prime(i)) @@ -50,26 +58,37 @@ int is_circular_prime(int n) { int i, tmp, count; + /* If n is not prime, it's obviously not a circular prime.*/ if(primes[n] == 0) { return 0; } + /* The primes below 10 are circular primes.*/ + if(primes[n] == 1 && n < 10) + { + return 1; + } + tmp = n; count = 0; while(tmp > 0) { + /* If the number has one or more even digits, it can't be a circular prime. + * because at least one of the rotations will be even.*/ if(tmp % 2 == 0) { return 0; } + /* Count the number of digits.*/ count++; tmp /= 10; } for(i = 1; i < count; i++) { + /* Generate rotations and check if it's primes.*/ n = n % (int)pow(10, count-1) * 10 + n / (int)pow(10, count-1); if(primes[n] == 0) {