Add comments

Added comments for problems 31, 32, 33, 34 and 35 in C.
This commit is contained in:
daniele 2019-09-25 17:42:58 +02:00
parent 85c692bd1b
commit 4ac079286e
Signed by: fuxino
GPG Key ID: 6FE25B4A3EE16FDA
6 changed files with 121 additions and 54 deletions

View File

@ -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++;

View File

@ -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
View File

@ -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]);
}

View File

@ -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);

View File

@ -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);

View File

@ -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)
{