Add comments
Added comments for problems 31, 32, 33, 34 and 35 in C.
This commit is contained in:
parent
85c692bd1b
commit
4ac079286e
2
C/p026.c
2
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
|
/* 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
|
* 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.
|
* 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))
|
while(!mpz_divisible_p(k, div))
|
||||||
{
|
{
|
||||||
n++;
|
n++;
|
||||||
|
11
C/p031.c
11
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 <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -28,6 +38,7 @@ int main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Simple recursive function that tries every combination.*/
|
||||||
int count(int value, int n, int i)
|
int count(int value, int n, int i)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
116
C/p032.c
116
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 <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "projecteuler.h"
|
#include "projecteuler.h"
|
||||||
|
|
||||||
@ -7,21 +17,23 @@ int compare(void *a, void *b);
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int a, b, i, j, k, p, p1, d, sum, n=0;
|
int a, b, i, j, p, sum, n = 0, num;
|
||||||
int digits[10];
|
|
||||||
int **products;
|
int **products;
|
||||||
|
char num_s[10];
|
||||||
double elapsed;
|
double elapsed;
|
||||||
struct timespec start, end;
|
struct timespec start, end;
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
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");
|
fprintf(stderr, "Error while allocating memory\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < 100; i++)
|
for(i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
if((products[i] = (int *)malloc(sizeof(int))) == NULL)
|
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;
|
p = i * j;
|
||||||
b = j;
|
sprintf(num_s, "%d%d%d", i, j, p);
|
||||||
p = a * b;
|
|
||||||
|
|
||||||
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;
|
*products[n] = p;
|
||||||
n++;
|
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];
|
sum = *products[0];
|
||||||
|
|
||||||
for(i = 1; i < 100; i++)
|
for(i = 1; i < n; i++)
|
||||||
{
|
{
|
||||||
if(*products[i] != *products[i-1])
|
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]);
|
free(products[i]);
|
||||||
}
|
}
|
||||||
|
15
C/p033.c
15
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 <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -5,7 +15,7 @@
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
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;
|
float f1, f2;
|
||||||
double elapsed;
|
double elapsed;
|
||||||
struct timespec start, end;
|
struct timespec start, end;
|
||||||
@ -16,6 +26,8 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
for(j = 11; j < 100; j++)
|
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)
|
if(i % 10 && j % 10 && i != j && i % 10 == j / 10)
|
||||||
{
|
{
|
||||||
n = i / 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);
|
div = gcd(prod_n, prod_d);
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||||
|
10
C/p034.c
10
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 <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -22,12 +28,14 @@ int main(int argc, char **argv)
|
|||||||
mpz_init_set_ui(factorials[i], 1);
|
mpz_init_set_ui(factorials[i], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Pre-calculate factorials of each digit from 0 to 9.*/
|
||||||
for(i = 2; i < 10; i++)
|
for(i = 2; i < 10; i++)
|
||||||
{
|
{
|
||||||
mpz_fac_ui(factorials[i], 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(b, a);
|
||||||
mpz_set_ui(sum_f, 0);
|
mpz_set_ui(sum_f, 0);
|
||||||
|
19
C/p035.c
19
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 <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -18,12 +24,14 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
|
||||||
|
/* Calculate all primes below one million, then check if they're circular.*/
|
||||||
if((primes = sieve(N)) == NULL)
|
if((primes = sieve(N)) == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error! Sieve function returned NULL\n");
|
fprintf(stderr, "Error! Sieve function returned NULL\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Starting from 101 because we already know that there are 13 circular primes below 100.*/
|
||||||
for(i = 101; i < 1000000; i += 2)
|
for(i = 101; i < 1000000; i += 2)
|
||||||
{
|
{
|
||||||
if(is_circular_prime(i))
|
if(is_circular_prime(i))
|
||||||
@ -50,26 +58,37 @@ int is_circular_prime(int n)
|
|||||||
{
|
{
|
||||||
int i, tmp, count;
|
int i, tmp, count;
|
||||||
|
|
||||||
|
/* If n is not prime, it's obviously not a circular prime.*/
|
||||||
if(primes[n] == 0)
|
if(primes[n] == 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The primes below 10 are circular primes.*/
|
||||||
|
if(primes[n] == 1 && n < 10)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
tmp = n;
|
tmp = n;
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
while(tmp > 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)
|
if(tmp % 2 == 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/* Count the number of digits.*/
|
||||||
count++;
|
count++;
|
||||||
tmp /= 10;
|
tmp /= 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 1; i < count; i++)
|
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);
|
n = n % (int)pow(10, count-1) * 10 + n / (int)pow(10, count-1);
|
||||||
if(primes[n] == 0)
|
if(primes[n] == 0)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user