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
|
||||
* 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++;
|
||||
|
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 <stdlib.h>
|
||||
#include <time.h>
|
||||
@ -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;
|
||||
|
118
C/p032.c
118
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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#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]);
|
||||
}
|
||||
|
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 <stdlib.h>
|
||||
#include <time.h>
|
||||
@ -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);
|
||||
|
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 <stdlib.h>
|
||||
#include <time.h>
|
||||
@ -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);
|
||||
|
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 <stdlib.h>
|
||||
#include <math.h>
|
||||
@ -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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user