Add comments
Added comments to the C code for problems from 16 to 25
This commit is contained in:
parent
b4c85f8f4a
commit
3f55f7c3d8
7
C/p016.c
7
C/p016.c
@ -1,3 +1,7 @@
|
|||||||
|
/* 2^15 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.
|
||||||
|
*
|
||||||
|
* What is the sum of the digits of the number 2^1000?*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -11,6 +15,8 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
|
||||||
|
/* Simply calculate 2^1000 with the GMP Library
|
||||||
|
* and sum all the digits.*/
|
||||||
mpz_init_set_ui(p, 2);
|
mpz_init_set_ui(p, 2);
|
||||||
mpz_init_set_ui(sum, 0);
|
mpz_init_set_ui(sum, 0);
|
||||||
mpz_init(r);
|
mpz_init(r);
|
||||||
@ -19,6 +25,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
while(mpz_cmp_ui(p, 0))
|
while(mpz_cmp_ui(p, 0))
|
||||||
{
|
{
|
||||||
|
/* To get each digit, simply get the reminder of the division by 10.*/
|
||||||
mpz_tdiv_qr_ui(p, r, p, 10);
|
mpz_tdiv_qr_ui(p, r, p, 10);
|
||||||
mpz_add(sum, sum, r);
|
mpz_add(sum, sum, r);
|
||||||
}
|
}
|
||||||
|
24
C/p017.c
24
C/p017.c
@ -1,12 +1,24 @@
|
|||||||
|
/* If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
|
||||||
|
*
|
||||||
|
* If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?
|
||||||
|
*
|
||||||
|
* NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen)
|
||||||
|
* contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage.*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
/* Number of letters for numbers from 1 to 19.*/
|
||||||
int n1_19[19] = {3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8};
|
int n1_19[19] = {3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8};
|
||||||
|
/* Number of letters for "twenty", "thirty", ..., "ninety".*/
|
||||||
int n20_90[8] = {6, 6, 5, 5, 5, 7, 6, 6};
|
int n20_90[8] = {6, 6, 5, 5, 5, 7, 6, 6};
|
||||||
|
/* Number of letters for "one hundred and", "two hundred and", ...,
|
||||||
|
* "nine hundred and".*/
|
||||||
int n100_900[9] = {13, 13, 15, 14, 14, 13, 15, 15, 14};
|
int n100_900[9] = {13, 13, 15, 14, 14, 13, 15, 15, 14};
|
||||||
|
/* Number of letters for 1000.*/
|
||||||
int n1000 = 11;
|
int n1000 = 11;
|
||||||
int sum = 0, i, j;
|
int sum = 0, i, j;
|
||||||
double elapsed;
|
double elapsed;
|
||||||
@ -14,14 +26,19 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
|
||||||
|
/* Sum the letters of the first 19 numbers.*/
|
||||||
for(i = 0; i < 19; i++)
|
for(i = 0; i < 19; i++)
|
||||||
{
|
{
|
||||||
sum += n1_19[i];
|
sum += n1_19[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add the letters of the numbers from 20 to 99.*/
|
||||||
for(i = 0; i < 8; i++)
|
for(i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
|
/* "Twenty", "thirty", ... "ninety" are used ten times each
|
||||||
|
* (e.g. "twenty", "twenty one", "twenty two", ..., "twenty nine").*/
|
||||||
n20_90[i] *= 10;
|
n20_90[i] *= 10;
|
||||||
|
/* Add "one", "two", ..., "nine".*/
|
||||||
for(j = 0; j < 9; j++)
|
for(j = 0; j < 9; j++)
|
||||||
{
|
{
|
||||||
n20_90[i] += n1_19[j];
|
n20_90[i] += n1_19[j];
|
||||||
@ -29,20 +46,27 @@ int main(int argc, char **argv)
|
|||||||
sum += n20_90[i];
|
sum += n20_90[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add the letters of the numbers from 100 to 999.*/
|
||||||
for(i = 0; i < 9; i++)
|
for(i = 0; i < 9; i++)
|
||||||
{
|
{
|
||||||
|
/* "One hundred and", "two hundred and",... are used 100 times each.*/
|
||||||
n100_900[i] *= 100;
|
n100_900[i] *= 100;
|
||||||
|
/* Add "one" to "nineteen".*/
|
||||||
for(j = 0; j < 19; j++)
|
for(j = 0; j < 19; j++)
|
||||||
{
|
{
|
||||||
n100_900[i] += n1_19[j];
|
n100_900[i] += n1_19[j];
|
||||||
}
|
}
|
||||||
|
/* Add "twenty" to "ninety nine", previously calculated.*/
|
||||||
for(j = 0; j < 8; j++)
|
for(j = 0; j < 8; j++)
|
||||||
{
|
{
|
||||||
n100_900[i] += n20_90[j];
|
n100_900[i] += n20_90[j];
|
||||||
}
|
}
|
||||||
|
/* "One hundred", "two hundred", ... don't have the "and", so remove
|
||||||
|
* three letters for each of them.*/
|
||||||
sum += n100_900[i] - 3;
|
sum += n100_900[i] - 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add "one thousand".*/
|
||||||
sum += n1000;
|
sum += n1000;
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||||
|
25
C/p019.c
25
C/p019.c
@ -1,3 +1,16 @@
|
|||||||
|
/* You are given the following information, but you may prefer to do some research for yourself.
|
||||||
|
*
|
||||||
|
* 1 Jan 1900 was a Monday.
|
||||||
|
* Thirty days has September,
|
||||||
|
* April, June and November.
|
||||||
|
* All the rest have thirty-one,
|
||||||
|
* Saving February alone,
|
||||||
|
* Which has twenty-eight, rain or shine.
|
||||||
|
* And on leap years, twenty-nine.
|
||||||
|
* A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
|
||||||
|
*
|
||||||
|
* How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -21,6 +34,9 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
while(year < 2001)
|
while(year < 2001)
|
||||||
{
|
{
|
||||||
|
/* February has 29 days on leap years, otherwise 28. Leap years are those
|
||||||
|
* divisible by 4, but not if they're divisible by 100, except when they're
|
||||||
|
* divisible by 400.*/
|
||||||
if(month == feb)
|
if(month == feb)
|
||||||
{
|
{
|
||||||
if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
|
if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
|
||||||
@ -32,24 +48,33 @@ int main(int argc, char **argv)
|
|||||||
limit = 28;
|
limit = 28;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* April, June, September and November have 30 days.*/
|
||||||
else if(month == apr || month == jun || month == sep || month == nov)
|
else if(month == apr || month == jun || month == sep || month == nov)
|
||||||
{
|
{
|
||||||
limit = 30;
|
limit = 30;
|
||||||
}
|
}
|
||||||
|
/* All other months have 31 days.*/
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
limit = 31;
|
limit = 31;
|
||||||
}
|
}
|
||||||
|
/* Loop on every day of the month.*/
|
||||||
for(i = 1; i <= limit; i++)
|
for(i = 1; i <= limit; i++)
|
||||||
{
|
{
|
||||||
|
/* If it's the first day of the month and it's Sunday, increase
|
||||||
|
* counter, except if year=1900 (we need to count Sundays from
|
||||||
|
* 1901 to 2000.*/
|
||||||
if(year > 1900 && i == 1 && day == sun)
|
if(year > 1900 && i == 1 && day == sun)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
/* Change day of the week.*/
|
||||||
day = (day + 1) % 7;
|
day = (day + 1) % 7;
|
||||||
}
|
}
|
||||||
|
/* At the end of the month, go to next month.*/
|
||||||
month = (month + 1) % 12;
|
month = (month + 1) % 12;
|
||||||
|
|
||||||
|
/* If we're back to january, increase the year.*/
|
||||||
if(month == jan)
|
if(month == jan)
|
||||||
{
|
{
|
||||||
year++;
|
year++;
|
||||||
|
8
C/p020.c
8
C/p020.c
@ -1,3 +1,10 @@
|
|||||||
|
/* n! means n × (n − 1) × ... × 3 × 2 × 1
|
||||||
|
*
|
||||||
|
* For example, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800,
|
||||||
|
* and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.
|
||||||
|
*
|
||||||
|
* Find the sum of the digits in the number 100!*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -11,6 +18,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
|
||||||
|
/* Calculate the factorial using the GMP Library and sum the digits.*/
|
||||||
mpz_inits(fact, r, sum, NULL);
|
mpz_inits(fact, r, sum, NULL);
|
||||||
|
|
||||||
mpz_fac_ui(fact, 100);
|
mpz_fac_ui(fact, 100);
|
||||||
|
40
C/p021.c
40
C/p021.c
@ -1,9 +1,16 @@
|
|||||||
|
/* Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n).
|
||||||
|
* If d(a) = b and d(b) = a, where a ≠ b, then a and b are an amicable pair and each of a and b are called amicable numbers.
|
||||||
|
*
|
||||||
|
* For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284.
|
||||||
|
* The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220.
|
||||||
|
|
||||||
|
Evaluate the sum of all the amicable numbers under 10000.*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include "projecteuler.h"
|
||||||
int sum_of_d(int n);
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -15,8 +22,12 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
for(i = 2; i < 10000; i++)
|
for(i = 2; i < 10000; i++)
|
||||||
{
|
{
|
||||||
n = sum_of_d(i);
|
/* Calculate the sum of proper divisors with the function
|
||||||
if(i != n && sum_of_d(n) == i)
|
* implemented in projecteuler.c.*/
|
||||||
|
n = sum_of_divisors(i);
|
||||||
|
/* If i!=n and the sum of proper divisors of n=i,
|
||||||
|
* sum the pair of numbers and add it to the total.*/
|
||||||
|
if(i != n && sum_of_divisors(n) == i)
|
||||||
{
|
{
|
||||||
sum += i + n;
|
sum += i + n;
|
||||||
}
|
}
|
||||||
@ -35,24 +46,3 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sum_of_d(int n)
|
|
||||||
{
|
|
||||||
int i, sum = 1, limit;
|
|
||||||
|
|
||||||
limit = floor(sqrt(n));
|
|
||||||
|
|
||||||
for(i = 2; i <= limit; i++)
|
|
||||||
{
|
|
||||||
if(n % i == 0)
|
|
||||||
{
|
|
||||||
sum += i;
|
|
||||||
if(n != i * i)
|
|
||||||
{
|
|
||||||
sum += (n / i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
13
C/p022.c
13
C/p022.c
@ -1,3 +1,11 @@
|
|||||||
|
/* Using names.txt, a 46K text file containing over five-thousand first names, begin by sorting it into alphabetical order.
|
||||||
|
* Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list to obtain a name score.
|
||||||
|
*
|
||||||
|
* For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list.
|
||||||
|
* So, COLIN would obtain a score of 938 × 53 = 49714.
|
||||||
|
*
|
||||||
|
* What is the total of all the name scores in the file?*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -29,6 +37,7 @@ int main(int argc, char **argv)
|
|||||||
len = strlen(line);
|
len = strlen(line);
|
||||||
n = 1;
|
n = 1;
|
||||||
|
|
||||||
|
/* Count the names in the file.*/
|
||||||
for(i = 0; i < len; i++)
|
for(i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
if(line[i] == ',')
|
if(line[i] == ',')
|
||||||
@ -43,6 +52,7 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save each name in a string.*/
|
||||||
names[0] = strtok(line, ",\"");
|
names[0] = strtok(line, ",\"");
|
||||||
|
|
||||||
for(i = 1; i < n; i++)
|
for(i = 1; i < n; i++)
|
||||||
@ -50,8 +60,10 @@ int main(int argc, char **argv)
|
|||||||
names[i] = strtok(NULL, ",\"");
|
names[i] = strtok(NULL, ",\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Use quick_sort algorithm implemented in projecteuler.c to sort the names.*/
|
||||||
quick_sort((void **)names, 0, n-1, compare);
|
quick_sort((void **)names, 0, n-1, compare);
|
||||||
|
|
||||||
|
/* Calculate the score of each name an multiply by its position.*/
|
||||||
for(i = 0; i < n; i++)
|
for(i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
len = strlen(names[i]);
|
len = strlen(names[i]);
|
||||||
@ -77,6 +89,7 @@ int main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Function to compare two strings, to pass to the quick_sort function.*/
|
||||||
int compare(void *string1, void *string2)
|
int compare(void *string1, void *string2)
|
||||||
{
|
{
|
||||||
char *s1, *s2;
|
char *s1, *s2;
|
||||||
|
54
C/p023.c
54
C/p023.c
@ -1,7 +1,20 @@
|
|||||||
|
/* A perfect number is a number for which the sum of its proper divisors is exactly equal to the number.
|
||||||
|
* For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
|
||||||
|
*
|
||||||
|
* A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
|
||||||
|
*
|
||||||
|
* As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24.
|
||||||
|
* By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers.
|
||||||
|
* However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed
|
||||||
|
* as the sum of two abundant numbers is less than this limit.
|
||||||
|
*
|
||||||
|
* Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include "projecteuler.h"
|
||||||
|
|
||||||
int is_abundant(int n);
|
int is_abundant(int n);
|
||||||
|
|
||||||
@ -16,20 +29,13 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
for(i = 0; i < 28123; i++)
|
for(i = 0; i < 28123; i++)
|
||||||
{
|
{
|
||||||
if(i < 11)
|
/* Find all abundant numbers smaller than 28123.*/
|
||||||
{
|
ab_nums[i] = is_abundant(i+1);
|
||||||
ab_nums[i] = 0;
|
|
||||||
}
|
|
||||||
else if(is_abundant(i+1))
|
|
||||||
{
|
|
||||||
ab_nums[i] = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ab_nums[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For every abundant number, sum every other abundant number greater
|
||||||
|
* than itself, until the sum exceeds 28123. Record that the resulting
|
||||||
|
* number is the sum of two abundant numbers.*/
|
||||||
for(i = 0; i < 28123; i++)
|
for(i = 0; i < 28123; i++)
|
||||||
{
|
{
|
||||||
if(ab_nums[i])
|
if(ab_nums[i])
|
||||||
@ -44,6 +50,10 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
sums[sum-1] = 1;
|
sums[sum-1] = 1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,6 +61,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
sum = 0;
|
sum = 0;
|
||||||
|
|
||||||
|
/* Sum every number that was not found as a sum of two abundant numbers.*/
|
||||||
for(i = 0; i < 28123; i++)
|
for(i = 0; i < 28123; i++)
|
||||||
{
|
{
|
||||||
if(!sums[i])
|
if(!sums[i])
|
||||||
@ -73,22 +84,5 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
int is_abundant(int n)
|
int is_abundant(int n)
|
||||||
{
|
{
|
||||||
int i, sum = 1, limit;
|
return sum_of_divisors(n) > n;
|
||||||
|
|
||||||
limit = floor(sqrt(n));
|
|
||||||
|
|
||||||
for(i = 2; i <= limit; i++)
|
|
||||||
{
|
|
||||||
if(n % i == 0)
|
|
||||||
{
|
|
||||||
sum += i;
|
|
||||||
|
|
||||||
if(n != i*i)
|
|
||||||
{
|
|
||||||
sum += (n / i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum > n;
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user