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 <stdlib.h>
|
||||
#include <time.h>
|
||||
@ -11,6 +15,8 @@ int main(int argc, char **argv)
|
||||
|
||||
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(sum, 0);
|
||||
mpz_init(r);
|
||||
@ -19,6 +25,7 @@ int main(int argc, char **argv)
|
||||
|
||||
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_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 <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
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};
|
||||
/* Number of letters for "twenty", "thirty", ..., "ninety".*/
|
||||
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};
|
||||
/* Number of letters for 1000.*/
|
||||
int n1000 = 11;
|
||||
int sum = 0, i, j;
|
||||
double elapsed;
|
||||
@ -14,14 +26,19 @@ int main(int argc, char **argv)
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
|
||||
/* Sum the letters of the first 19 numbers.*/
|
||||
for(i = 0; i < 19; i++)
|
||||
{
|
||||
sum += n1_19[i];
|
||||
}
|
||||
|
||||
/* Add the letters of the numbers from 20 to 99.*/
|
||||
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;
|
||||
/* Add "one", "two", ..., "nine".*/
|
||||
for(j = 0; j < 9; j++)
|
||||
{
|
||||
n20_90[i] += n1_19[j];
|
||||
@ -29,20 +46,27 @@ int main(int argc, char **argv)
|
||||
sum += n20_90[i];
|
||||
}
|
||||
|
||||
/* Add the letters of the numbers from 100 to 999.*/
|
||||
for(i = 0; i < 9; i++)
|
||||
{
|
||||
/* "One hundred and", "two hundred and",... are used 100 times each.*/
|
||||
n100_900[i] *= 100;
|
||||
/* Add "one" to "nineteen".*/
|
||||
for(j = 0; j < 19; j++)
|
||||
{
|
||||
n100_900[i] += n1_19[j];
|
||||
}
|
||||
/* Add "twenty" to "ninety nine", previously calculated.*/
|
||||
for(j = 0; j < 8; 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;
|
||||
}
|
||||
|
||||
/* Add "one thousand".*/
|
||||
sum += n1000;
|
||||
|
||||
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 <stdlib.h>
|
||||
#include <time.h>
|
||||
@ -21,6 +34,9 @@ int main(int argc, char **argv)
|
||||
|
||||
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(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
|
||||
@ -32,24 +48,33 @@ int main(int argc, char **argv)
|
||||
limit = 28;
|
||||
}
|
||||
}
|
||||
/* April, June, September and November have 30 days.*/
|
||||
else if(month == apr || month == jun || month == sep || month == nov)
|
||||
{
|
||||
limit = 30;
|
||||
}
|
||||
/* All other months have 31 days.*/
|
||||
else
|
||||
{
|
||||
limit = 31;
|
||||
}
|
||||
/* Loop on every day of the month.*/
|
||||
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)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
/* Change day of the week.*/
|
||||
day = (day + 1) % 7;
|
||||
}
|
||||
/* At the end of the month, go to next month.*/
|
||||
month = (month + 1) % 12;
|
||||
|
||||
/* If we're back to january, increase the year.*/
|
||||
if(month == jan)
|
||||
{
|
||||
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 <stdlib.h>
|
||||
#include <time.h>
|
||||
@ -11,6 +18,7 @@ int main(int argc, char **argv)
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
|
||||
/* Calculate the factorial using the GMP Library and sum the digits.*/
|
||||
mpz_inits(fact, r, sum, NULL);
|
||||
|
||||
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 <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
int sum_of_d(int n);
|
||||
#include "projecteuler.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@ -15,8 +22,12 @@ int main(int argc, char **argv)
|
||||
|
||||
for(i = 2; i < 10000; i++)
|
||||
{
|
||||
n = sum_of_d(i);
|
||||
if(i != n && sum_of_d(n) == i)
|
||||
/* Calculate the sum of proper divisors with the function
|
||||
* 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;
|
||||
}
|
||||
@ -35,24 +46,3 @@ int main(int argc, char **argv)
|
||||
|
||||
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 <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -29,6 +37,7 @@ int main(int argc, char **argv)
|
||||
len = strlen(line);
|
||||
n = 1;
|
||||
|
||||
/* Count the names in the file.*/
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
if(line[i] == ',')
|
||||
@ -43,6 +52,7 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Save each name in a string.*/
|
||||
names[0] = strtok(line, ",\"");
|
||||
|
||||
for(i = 1; i < n; i++)
|
||||
@ -50,8 +60,10 @@ int main(int argc, char **argv)
|
||||
names[i] = strtok(NULL, ",\"");
|
||||
}
|
||||
|
||||
/* Use quick_sort algorithm implemented in projecteuler.c to sort the names.*/
|
||||
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++)
|
||||
{
|
||||
len = strlen(names[i]);
|
||||
@ -77,6 +89,7 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Function to compare two strings, to pass to the quick_sort function.*/
|
||||
int compare(void *string1, void *string2)
|
||||
{
|
||||
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 <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include "projecteuler.h"
|
||||
|
||||
int is_abundant(int n);
|
||||
|
||||
@ -16,20 +29,13 @@ int main(int argc, char **argv)
|
||||
|
||||
for(i = 0; i < 28123; i++)
|
||||
{
|
||||
if(i < 11)
|
||||
{
|
||||
ab_nums[i] = 0;
|
||||
}
|
||||
else if(is_abundant(i+1))
|
||||
{
|
||||
ab_nums[i] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ab_nums[i] = 0;
|
||||
}
|
||||
/* Find all abundant numbers smaller than 28123.*/
|
||||
ab_nums[i] = is_abundant(i+1);
|
||||
}
|
||||
|
||||
/* 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++)
|
||||
{
|
||||
if(ab_nums[i])
|
||||
@ -44,6 +50,10 @@ int main(int argc, char **argv)
|
||||
{
|
||||
sums[sum-1] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -51,6 +61,7 @@ int main(int argc, char **argv)
|
||||
|
||||
sum = 0;
|
||||
|
||||
/* Sum every number that was not found as a sum of two abundant numbers.*/
|
||||
for(i = 0; i < 28123; i++)
|
||||
{
|
||||
if(!sums[i])
|
||||
@ -73,22 +84,5 @@ int main(int argc, char **argv)
|
||||
|
||||
int is_abundant(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 > n;
|
||||
return sum_of_divisors(n) > n;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user