Add comments
Added comments to the C code for all the problems solved so far.
This commit is contained in:
parent
9df4d3fe97
commit
ecdbadba7e
48
C/p024.c
48
C/p024.c
@ -10,8 +10,6 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "projecteuler.h"
|
#include "projecteuler.h"
|
||||||
|
|
||||||
void next_perm(int **perm, int n);
|
|
||||||
void swap(int **vet, int i, int j);
|
|
||||||
int compare(void *a, void *b);
|
int compare(void *a, void *b);
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@ -43,7 +41,7 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
/* Function that generates permutations in lexicographic order.
|
/* Function that generates permutations in lexicographic order.
|
||||||
* Finish when the 1000000th is found.*/
|
* Finish when the 1000000th is found.*/
|
||||||
next_perm(perm, 10);
|
next_permutation((void **)perm, 10, compare);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < 10; i++)
|
for(i = 0; i < 10; i++)
|
||||||
@ -73,15 +71,6 @@ int main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(int **vet, int i, int j)
|
|
||||||
{
|
|
||||||
int *tmp;
|
|
||||||
|
|
||||||
tmp = vet[i];
|
|
||||||
vet[i] = vet[j];
|
|
||||||
vet[j] = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
int compare(void *a, void *b)
|
int compare(void *a, void *b)
|
||||||
{
|
{
|
||||||
int *n1, *n2;
|
int *n1, *n2;
|
||||||
@ -91,38 +80,3 @@ int compare(void *a, void *b)
|
|||||||
|
|
||||||
return *n1 - *n2;
|
return *n1 - *n2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implements SEPA (Simple, Efficient Permutation Algorithm)
|
|
||||||
* to find the next permutation.*/
|
|
||||||
void next_perm(int **perm, int n)
|
|
||||||
{
|
|
||||||
int i, key;
|
|
||||||
|
|
||||||
/* Starting from the right of the array, for each pair of values
|
|
||||||
* if the left one is smaller than the right, that value is the key.*/
|
|
||||||
for(i = n - 2; i >= 0; i--)
|
|
||||||
{
|
|
||||||
if(compare((void *)perm[i], (void *)perm[i+1]) < 0)
|
|
||||||
{
|
|
||||||
key = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If no left value is smaller than its right value, the
|
|
||||||
* array is in reverse order, i.e. it's the last permutation.*/
|
|
||||||
if(i == -1)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the smallest value on the right of the key which is bigger than the key itself,
|
|
||||||
* considering that the values at the right of the key are in reverse order.*/
|
|
||||||
for(i = key + 1; i < n && compare((void *)perm[i], (void *)perm[key]) > 0; i++);
|
|
||||||
|
|
||||||
/* Swap the value found and the key.*/
|
|
||||||
swap(perm, key, i-1);
|
|
||||||
/* Sort the values at the right of the key. This is
|
|
||||||
* the next permutation.*/
|
|
||||||
insertion_sort((void **)perm, key+1, n-1, compare);
|
|
||||||
}
|
|
||||||
|
24
C/p041.c
24
C/p041.c
@ -1,3 +1,8 @@
|
|||||||
|
/* 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, 2143 is a 4-digit pandigital
|
||||||
|
* and is also prime.
|
||||||
|
*
|
||||||
|
* What is the largest n-digit pandigital prime that exists?*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -8,27 +13,34 @@ int count_digits(int n);
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i, found = 0;
|
/* 8- and 9-digit pandigital numbers can't be prime, because
|
||||||
|
* 1+2+...+8=36, which is divisible by 3, and 36+9=45 which is
|
||||||
|
* also divisible by 3, and therefore the whole number is divisible
|
||||||
|
* by 3. So we can start from the largest 7-digit pandigital number,
|
||||||
|
* until we find a prime.*/
|
||||||
|
int i = 7654321;
|
||||||
double elapsed;
|
double elapsed;
|
||||||
struct timespec start, end;
|
struct timespec start, end;
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
|
||||||
for(i = 7654321; !found && i > 0; i -= 2)
|
while(i > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(is_pandigital(i, count_digits(i)) && is_prime(i))
|
if(is_pandigital(i, count_digits(i)) && is_prime(i))
|
||||||
{
|
{
|
||||||
printf("Project Euler, Problem 41\n");
|
break;
|
||||||
printf("Answer: %d\n", i);
|
|
||||||
found = 1;
|
|
||||||
}
|
}
|
||||||
|
// Skipping the even numbers.
|
||||||
|
i -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
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 41\n");
|
||||||
|
printf("Answer: %d\n", i);
|
||||||
|
|
||||||
printf("Elapsed time: %.9lf seconds\n", elapsed);
|
printf("Elapsed time: %.9lf seconds\n", elapsed);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
13
C/p042.c
13
C/p042.c
@ -1,3 +1,13 @@
|
|||||||
|
/* The nth term of the sequence of triangle numbers is given by, tn = ½n(n+1); so the first ten triangle numbers are:
|
||||||
|
*
|
||||||
|
* 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
|
||||||
|
*
|
||||||
|
* By converting each letter in a word to a number corresponding to its alphabetical position and adding these values we form a word value.
|
||||||
|
* For example, the word value for SKY is 19 + 11 + 25 = 55 = t10. If the word value is a triangle number then we shall call the word a triangle word.
|
||||||
|
*
|
||||||
|
* Using words.txt (right click and 'Save Link/Target As...'), a 16K text file containing nearly two-thousand common English words,
|
||||||
|
* how many are triangle words?*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -28,6 +38,7 @@ int main(int argc, char **argv)
|
|||||||
n = 1;
|
n = 1;
|
||||||
len = strlen(line);
|
len = strlen(line);
|
||||||
|
|
||||||
|
/* Count the words.*/
|
||||||
for(i = 0; i < len; i++)
|
for(i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
if(line[i] == ',')
|
if(line[i] == ',')
|
||||||
@ -42,6 +53,7 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save the words in an array of strings.*/
|
||||||
words[0] = strtok(line, ",\"");
|
words[0] = strtok(line, ",\"");
|
||||||
|
|
||||||
for(i = 1; i < n; i++)
|
for(i = 1; i < n; i++)
|
||||||
@ -49,6 +61,7 @@ int main(int argc, char **argv)
|
|||||||
words[i] = strtok(NULL, ",\"");
|
words[i] = strtok(NULL, ",\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For each word, calculate its value and check if it's a triangle number.*/
|
||||||
for(i = 0; i < n; i++)
|
for(i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
value = 0;
|
value = 0;
|
||||||
|
12
C/p044.c
12
C/p044.c
@ -1,3 +1,12 @@
|
|||||||
|
/* Pentagonal numbers are generated by the formula, Pn=n(3n−1)/2. The first ten pentagonal numbers are:
|
||||||
|
*
|
||||||
|
* 1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ...
|
||||||
|
*
|
||||||
|
* It can be seen that P4 + P7 = 22 + 70 = 92 = P8. However, their difference, 70 − 22 = 48, is not pentagonal.
|
||||||
|
*
|
||||||
|
* Find the pair of pentagonal numbers, Pj and Pk, for which their sum and difference are pentagonal and D = |Pk − Pj| is minimised;
|
||||||
|
* what is the value of D?*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -14,6 +23,9 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
n = 2;
|
n = 2;
|
||||||
|
|
||||||
|
/* Check all couples of pentagonal numbers until the right one
|
||||||
|
* is found. Use the function implemented in projecteuler.c to
|
||||||
|
* check if the sum and difference ot the two numbers is pentagonal.*/
|
||||||
while(!found)
|
while(!found)
|
||||||
{
|
{
|
||||||
pn = n * (3 * n - 1) / 2;
|
pn = n * (3 * n - 1) / 2;
|
||||||
|
13
C/p045.c
13
C/p045.c
@ -1,3 +1,13 @@
|
|||||||
|
/* Triangle, pentagonal, and hexagonal numbers are generated by the following formulae:
|
||||||
|
*
|
||||||
|
* Triangle T_n=n(n+1)/2 1, 3, 6, 10, 15, ...
|
||||||
|
* Pentagonal P_n=n(3n−1)/2 1, 5, 12, 22, 35, ...
|
||||||
|
* Hexagonal H_n=n(2n−1) 1, 6, 15, 28, 45, ...
|
||||||
|
*
|
||||||
|
* It can be verified that T_285 = P_165 = H_143 = 40755.
|
||||||
|
*
|
||||||
|
* Find the next triangle number that is also pentagonal and hexagonal.*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -18,6 +28,9 @@ int main(int argc, char **argv)
|
|||||||
while(!found)
|
while(!found)
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
|
/* Hexagonal numbers are also triangle numbers, so it's sufficient
|
||||||
|
* to generate hexagonal numbers (starting from H_144) and check if
|
||||||
|
* they're also pentagonal.*/
|
||||||
n = i * (2 * i - 1);
|
n = i * (2 * i - 1);
|
||||||
|
|
||||||
if(is_pentagonal(n))
|
if(is_pentagonal(n))
|
||||||
|
23
C/p047.c
23
C/p047.c
@ -1,3 +1,16 @@
|
|||||||
|
/* The first two consecutive numbers to have two distinct prime factors are:
|
||||||
|
*
|
||||||
|
* 14 = 2 × 7
|
||||||
|
* 15 = 3 × 5
|
||||||
|
*
|
||||||
|
* The first three consecutive numbers to have three distinct prime factors are:
|
||||||
|
*
|
||||||
|
* 644 = 2² × 7 × 23
|
||||||
|
* 645 = 3 × 5 × 43
|
||||||
|
* 646 = 2 × 17 × 19.
|
||||||
|
*
|
||||||
|
* Find the first four consecutive integers to have four distinct prime factors each. What is the first of these numbers?*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -24,7 +37,9 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 645; !found && i < N - 3; i++)
|
/* Starting from 647, count the distinct prime factors of n, n+1, n+2 and n+3.
|
||||||
|
* If they all have 4, the solution is found.*/
|
||||||
|
for(i = 647; !found && i < N - 3; i++)
|
||||||
{
|
{
|
||||||
if(!primes[i] && !primes[i+1] && !primes[i+2] && !primes[i+3])
|
if(!primes[i] && !primes[i+1] && !primes[i+2] && !primes[i+3])
|
||||||
{
|
{
|
||||||
@ -54,6 +69,8 @@ int count_distinct_factors(int n)
|
|||||||
{
|
{
|
||||||
int i, count=0;
|
int i, count=0;
|
||||||
|
|
||||||
|
/* Start checking if 2 is a prime factor of n. Then remove
|
||||||
|
* all 2s factore.*/
|
||||||
if(n % 2 == 0)
|
if(n % 2 == 0)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
@ -64,6 +81,10 @@ int count_distinct_factors(int n)
|
|||||||
}while(n % 2 == 0);
|
}while(n % 2 == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check all odd numbers i, if they're prime and they're a factor
|
||||||
|
* of n, count them and then divide n for by i until all factors i
|
||||||
|
* are eliminated. Stop the loop when n=1, i.e. all factors have
|
||||||
|
* been found.*/
|
||||||
for(i = 3; n > 1; i += 2)
|
for(i = 3; n > 1; i += 2)
|
||||||
{
|
{
|
||||||
if(primes[i] && n % i == 0)
|
if(primes[i] && n % i == 0)
|
||||||
|
5
C/p048.c
5
C/p048.c
@ -1,3 +1,7 @@
|
|||||||
|
/* The series, 1^1 + 2^2 + 3^3 + ... + 10^10 = 10405071317.
|
||||||
|
*
|
||||||
|
* Find the last ten digits of the series, 1^1 + 2^2 + 3^3 + ... + 1000^1000.*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -17,6 +21,7 @@ int main(int argc, char **argv)
|
|||||||
mpz_init_set_ui(sum, 0);
|
mpz_init_set_ui(sum, 0);
|
||||||
mpz_init(power);
|
mpz_init(power);
|
||||||
|
|
||||||
|
/* Simply calculate the sum of the powers using the GMP Library.*/
|
||||||
for(i = 1; i <= 1000; i++)
|
for(i = 1; i <= 1000; i++)
|
||||||
{
|
{
|
||||||
mpz_ui_pow_ui(power, i, i);
|
mpz_ui_pow_ui(power, i, i);
|
||||||
|
27
C/p049.c
27
C/p049.c
@ -1,3 +1,11 @@
|
|||||||
|
/* The arithmetic sequence, 1487, 4817, 8147, in which each of the terms increases by 3330, is unusual in two ways: (i) each of the three terms are prime,
|
||||||
|
* and, (ii) each of the 4-digit numbers are permutations of one another.
|
||||||
|
*
|
||||||
|
* There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes, exhibiting this property, but there is one other 4-digit
|
||||||
|
* increasing sequence.
|
||||||
|
*
|
||||||
|
* What 12-digit number do you form by concatenating the three terms in this sequence?*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -12,7 +20,7 @@ int *primes;
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i, j, found = 0;
|
int i = 1489, j, found = 0;
|
||||||
double elapsed;
|
double elapsed;
|
||||||
struct timespec start, end;
|
struct timespec start, end;
|
||||||
|
|
||||||
@ -24,12 +32,18 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 1489; i < N && !found; i++)
|
/* Starting from i=1489 (bigger than the first number in the sequence given in the problem),
|
||||||
|
* check odd numbers. If they're prime, loop on even numbers j (odd+even=odd, odd+odd=even and
|
||||||
|
* we need odd numbers because we're looking for primes) up to 4254 (1489+2*4256=10001 which has
|
||||||
|
* 5 digits.*/
|
||||||
|
while(i < N)
|
||||||
{
|
{
|
||||||
if(primes[i])
|
if(primes[i])
|
||||||
{
|
{
|
||||||
for(j = 1; j < 4255; j++)
|
for(j = 2; j < 4255; j += 2)
|
||||||
{
|
{
|
||||||
|
/* 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] &&
|
if(i + 2 * j < N && primes[i+j] && primes[i+2*j] &&
|
||||||
check_digits(i, i+j) && check_digits(i, i+2*j))
|
check_digits(i, i+j) && check_digits(i, i+2*j))
|
||||||
{
|
{
|
||||||
@ -38,6 +52,11 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(found)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(primes);
|
free(primes);
|
||||||
@ -47,7 +66,7 @@ int main(int argc, char **argv)
|
|||||||
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 49\n");
|
printf("Project Euler, Problem 49\n");
|
||||||
printf("Answer: %d%d%d\n", i-1, i-1+j, i-1+2*j);
|
printf("Answer: %d%d%d\n", i, i+j, i+2*j);
|
||||||
|
|
||||||
printf("Elapsed time: %.9lf seconds\n", elapsed);
|
printf("Elapsed time: %.9lf seconds\n", elapsed);
|
||||||
|
|
||||||
|
39
C/p050.c
39
C/p050.c
@ -1,3 +1,13 @@
|
|||||||
|
/* The prime 41, can be written as the sum of six consecutive primes:
|
||||||
|
*
|
||||||
|
* 41 = 2 + 3 + 5 + 7 + 11 + 13
|
||||||
|
*
|
||||||
|
* This is the longest sum of consecutive primes that adds to a prime below one-hundred.
|
||||||
|
*
|
||||||
|
* The longest sum of consecutive primes below one-thousand that adds to a prime, contains 21 terms, and is equal to 953.
|
||||||
|
*
|
||||||
|
* Which prime, below one-million, can be written as the sum of the most consecutive primes?*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -21,14 +31,39 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 2; i < N; i++)
|
/* Starting from a prime i, add consecutive primes until the
|
||||||
|
* sum exceeds the limit, every time the sum is also a prime
|
||||||
|
* save the value and the count if the count is larger than the
|
||||||
|
* current maximum. Repeat for all primes below N.
|
||||||
|
* A separate loop is used for i=2, so later only odd numbers are
|
||||||
|
* checked for primality.*/
|
||||||
|
i = 2;
|
||||||
|
count = 1;
|
||||||
|
sum = i;
|
||||||
|
|
||||||
|
for(j = i + 1; j < N && sum < N; j++)
|
||||||
|
{
|
||||||
|
if(primes[j])
|
||||||
|
{
|
||||||
|
sum += j;
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if(sum < N && primes[sum] && count > max)
|
||||||
|
{
|
||||||
|
max = count;
|
||||||
|
max_p = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 3; i < N; i += 2)
|
||||||
{
|
{
|
||||||
if(primes[i])
|
if(primes[i])
|
||||||
{
|
{
|
||||||
count = 1;
|
count = 1;
|
||||||
sum = i;
|
sum = i;
|
||||||
|
|
||||||
for(j = i + 1; j < N && sum < N; j++)
|
for(j = i + 2; j < N && sum < N; j += 2)
|
||||||
{
|
{
|
||||||
if(primes[j])
|
if(primes[j])
|
||||||
{
|
{
|
||||||
|
@ -15,14 +15,18 @@ def count_digits(n):
|
|||||||
def main():
|
def main():
|
||||||
start = default_timer()
|
start = default_timer()
|
||||||
|
|
||||||
for i in range(7654321, 0, -2):
|
i = 7654321
|
||||||
|
|
||||||
|
while(i > 0):
|
||||||
if is_pandigital(i, count_digits(i)) and is_prime(i):
|
if is_pandigital(i, count_digits(i)) and is_prime(i):
|
||||||
print('Project Euler, Problem 41')
|
|
||||||
print('Answer: {}'.format(i))
|
|
||||||
break
|
break
|
||||||
|
i = i - 2
|
||||||
|
|
||||||
end = default_timer()
|
end = default_timer()
|
||||||
|
|
||||||
|
print('Project Euler, Problem 41')
|
||||||
|
print('Answer: {}'.format(i))
|
||||||
|
|
||||||
print('Elapsed time: {:.9f} seconds'.format(end - start))
|
print('Elapsed time: {:.9f} seconds'.format(end - start))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
Loading…
x
Reference in New Issue
Block a user