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 "projecteuler.h"
|
||||
|
||||
void next_perm(int **perm, int n);
|
||||
void swap(int **vet, int i, int j);
|
||||
int compare(void *a, void *b);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
@ -43,7 +41,7 @@ int main(int argc, char **argv)
|
||||
{
|
||||
/* Function that generates permutations in lexicographic order.
|
||||
* Finish when the 1000000th is found.*/
|
||||
next_perm(perm, 10);
|
||||
next_permutation((void **)perm, 10, compare);
|
||||
}
|
||||
|
||||
for(i = 0; i < 10; i++)
|
||||
@ -73,15 +71,6 @@ int main(int argc, char **argv)
|
||||
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 *n1, *n2;
|
||||
@ -91,38 +80,3 @@ int compare(void *a, void *b)
|
||||
|
||||
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 <stdlib.h>
|
||||
#include <math.h>
|
||||
@ -8,27 +13,34 @@ int count_digits(int n);
|
||||
|
||||
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;
|
||||
struct timespec start, end;
|
||||
|
||||
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))
|
||||
{
|
||||
printf("Project Euler, Problem 41\n");
|
||||
printf("Answer: %d\n", i);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
// Skipping the even numbers.
|
||||
i -= 2;
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||
|
||||
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);
|
||||
|
||||
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 <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -28,6 +38,7 @@ int main(int argc, char **argv)
|
||||
n = 1;
|
||||
len = strlen(line);
|
||||
|
||||
/* Count the words.*/
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
if(line[i] == ',')
|
||||
@ -42,6 +53,7 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Save the words in an array of strings.*/
|
||||
words[0] = strtok(line, ",\"");
|
||||
|
||||
for(i = 1; i < n; i++)
|
||||
@ -49,6 +61,7 @@ int main(int argc, char **argv)
|
||||
words[i] = strtok(NULL, ",\"");
|
||||
}
|
||||
|
||||
/* For each word, calculate its value and check if it's a triangle number.*/
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
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 <stdlib.h>
|
||||
#include <math.h>
|
||||
@ -14,6 +23,9 @@ int main(int argc, char **argv)
|
||||
|
||||
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)
|
||||
{
|
||||
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 <stdlib.h>
|
||||
#include <math.h>
|
||||
@ -18,6 +28,9 @@ int main(int argc, char **argv)
|
||||
while(!found)
|
||||
{
|
||||
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);
|
||||
|
||||
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 <stdlib.h>
|
||||
#include <math.h>
|
||||
@ -24,7 +37,9 @@ int main(int argc, char **argv)
|
||||
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])
|
||||
{
|
||||
@ -54,6 +69,8 @@ int count_distinct_factors(int n)
|
||||
{
|
||||
int i, count=0;
|
||||
|
||||
/* Start checking if 2 is a prime factor of n. Then remove
|
||||
* all 2s factore.*/
|
||||
if(n % 2 == 0)
|
||||
{
|
||||
count++;
|
||||
@ -64,6 +81,10 @@ int count_distinct_factors(int n)
|
||||
}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)
|
||||
{
|
||||
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 <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -17,6 +21,7 @@ int main(int argc, char **argv)
|
||||
mpz_init_set_ui(sum, 0);
|
||||
mpz_init(power);
|
||||
|
||||
/* Simply calculate the sum of the powers using the GMP Library.*/
|
||||
for(i = 1; i <= 1000; 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 <stdlib.h>
|
||||
#include <math.h>
|
||||
@ -12,7 +20,7 @@ int *primes;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, j, found = 0;
|
||||
int i = 1489, j, found = 0;
|
||||
double elapsed;
|
||||
struct timespec start, end;
|
||||
|
||||
@ -24,12 +32,18 @@ int main(int argc, char **argv)
|
||||
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])
|
||||
{
|
||||
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] &&
|
||||
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);
|
||||
@ -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;
|
||||
|
||||
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);
|
||||
|
||||
|
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 <stdlib.h>
|
||||
#include <math.h>
|
||||
@ -21,14 +31,39 @@ int main(int argc, char **argv)
|
||||
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])
|
||||
{
|
||||
count = 1;
|
||||
sum = i;
|
||||
|
||||
for(j = i + 1; j < N && sum < N; j++)
|
||||
for(j = i + 2; j < N && sum < N; j += 2)
|
||||
{
|
||||
if(primes[j])
|
||||
{
|
||||
|
@ -15,14 +15,18 @@ def count_digits(n):
|
||||
def main():
|
||||
start = default_timer()
|
||||
|
||||
for i in range(7654321, 0, -2):
|
||||
if is_pandigital(i, count_digits(i)) and is_prime(i):
|
||||
print('Project Euler, Problem 41')
|
||||
print('Answer: {}'.format(i))
|
||||
break
|
||||
i = 7654321
|
||||
|
||||
while(i > 0):
|
||||
if is_pandigital(i, count_digits(i)) and is_prime(i):
|
||||
break
|
||||
i = i - 2
|
||||
|
||||
end = default_timer()
|
||||
|
||||
print('Project Euler, Problem 41')
|
||||
print('Answer: {}'.format(i))
|
||||
|
||||
print('Elapsed time: {:.9f} seconds'.format(end - start))
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
Loading…
x
Reference in New Issue
Block a user