Add comments

Added comments to the C code for problems from 16 to 25
This commit is contained in:
daniele 2019-09-23 20:14:26 +02:00
parent b4c85f8f4a
commit 3f55f7c3d8
Signed by: fuxino
GPG Key ID: 6FE25B4A3EE16FDA
7 changed files with 116 additions and 55 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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