fix: Remove the Project Euler folder

We've recently received an email from the Project Euler team that we should remove the folders
including problems/files from the Project Euler. It seems they don't want us to have them in our repositories.

Sorry about your effort in adding them, but we need to remove them from our repositories.
This commit is contained in:
David Leal 2021-05-10 11:24:48 -05:00
parent fb778074c7
commit 454bc8b771
No known key found for this signature in database
GPG Key ID: 3C482B03FD220E68
41 changed files with 0 additions and 2884 deletions

View File

@ -58,7 +58,6 @@ add_subdirectory(graphics)
add_subdirectory(searching)
add_subdirectory(conversions)
add_subdirectory(client_server)
add_subdirectory(project_euler)
add_subdirectory(machine_learning)
add_subdirectory(numerical_methods)

View File

@ -1,24 +0,0 @@
# If necessary, use the RELATIVE flag, otherwise each source file may be listed
# with full pathname. RELATIVE may makes it easier to extract an executable name
# automatically.
file( GLOB_RECURSE APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c )
# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c )
# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES)
foreach( testsourcefile ${APP_SOURCES} )
# I used a simple string replace, to cut off .cpp.
string( REPLACE ".c" "" testname ${testsourcefile} )
string( REPLACE "/" "-" testname ${testname} )
string( REPLACE "\\" "-" testname ${testname} )
string( REPLACE " " "_" testname ${testname} )
add_executable( ${testname} ${testsourcefile} )
if(OpenMP_C_FOUND)
target_link_libraries(${testname} OpenMP::OpenMP_C)
endif()
if(MATH_LIBRARY)
target_link_libraries(${testname} ${MATH_LIBRARY})
endif()
install(TARGETS ${testname} DESTINATION "bin/project_euler")
endforeach( testsourcefile ${APP_SOURCES} )

View File

@ -1,39 +0,0 @@
# ProjectEuler
Problems are taken from https://projecteuler.net/.
Project Euler is a series of challenging mathematical/computer programming problems that will require more than just mathematical
insights to solve. Project Euler is ideal for mathematicians who are learning to code.
Here the efficiency of your code is also checked.
I've tried to provide all the best possible solutions.
PROBLEMS:
1. If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3,5,6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below N.
2. Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2,
the first 10 terms will be:
1,2,3,5,8,13,21,34,55,89,..
By considering the terms in the Fibonacci sequence whose values do not exceed n, find the sum of the even-valued terms.
e.g. for n=10, we have {2,8}, sum is 10.
3. The prime factors of 13195 are 5,7,13 and 29. What is the largest prime factor of a given number N?
e.g. for 10, largest prime factor = 5. For 17, largest prime factor = 17.
4. A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers which is less than N.
5. 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible(divisible with no remainder) by all of the numbers from 1 to N?
6. The sum of the squares of the first ten natural numbers is,
1^2 + 2^2 + ... + 10^2 = 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)^2 = 552 = 3025
Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 385 = 2640.
Find the difference between the sum of the squares of the first N natural numbers and the square of the sum.
7. By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the Nth prime number?

View File

@ -1,35 +0,0 @@
/**
* \file
* \brief [Problem 1](https://projecteuler.net/problem=1) solution
* \details
* An Efficient code to print all the sum of all numbers that are multiples of 3
* & 5 below N.
*/
#include <stdio.h>
/** Main function */
int main()
{
int t;
printf("Enter number of times you want to try");
scanf("%d", &t);
while (t--) // while t > 0, decrement 't' before every iteration
{
unsigned long long N, p = 0, sum = 0;
printf("Enter the value of N ");
scanf("%lld", &N); // Take input of N from user
p = (N - 1) / 3;
sum = ((3 * p * (p + 1)) / 2);
p = (N - 1) / 5;
sum = sum + ((5 * p * (p + 1)) / 2);
p = (N - 1) / 15;
sum = sum - ((15 * p * (p + 1)) / 2);
printf("%lld\n", sum); // print the sum of all numbers that are
// multiples of 3 & 5 below N
}
return 0;
}

View File

@ -1,29 +0,0 @@
/**
* \file
* \brief [Problem 1](https://projecteuler.net/problem=1) solution
*
* If we list all the natural numbers below 10 that are multiples of 3 or 5,
* we get 3,5,6 and 9. The sum of these multiples is 23.
* Find the sum of all the multiples of 3 or 5 below N.
*
* This solution is based on the pattern that the successive numbers in the
* series follow: 0+3,+2,+1,+3,+1,+2,+3.
*/
#include <stdio.h>
/** Main function */
int main()
{
int n = 0;
int sum = 0;
scanf("%d", &n);
int terms = (n - 1) / 3;
sum += ((terms) * (6 + (terms - 1) * 3)) / 2; // sum of an A.P.
terms = (n - 1) / 5;
sum += ((terms) * (10 + (terms - 1) * 5)) / 2;
terms = (n - 1) / 15;
sum -= ((terms) * (30 + (terms - 1) * 15)) / 2;
printf("%d\n", sum);
}

View File

@ -1,55 +0,0 @@
/**
* \file
* \brief [Problem 1](https://projecteuler.net/problem=1) solution.
* This solution is based on the pattern that the successive numbers in the
* series follow: 0+3,+2,+1,+3,+1,+2,+3.
*
* If we list all the natural numbers below 10 that are multiples of 3 or 5,
* we get 3,5,6 and 9. The sum of these multiples is 23.
* Find the sum of all the multiples of 3 or 5 below N.
*/
#include <stdio.h>
/** Main function */
int main()
{
int n = 0;
int sum = 0;
int num = 0;
scanf("%d", &n);
while (1)
{
num += 3;
if (num >= n)
break;
sum += num;
num += 2;
if (num >= n)
break;
sum += num;
num += 1;
if (num >= n)
break;
sum += num;
num += 3;
if (num >= n)
break;
sum += num;
num += 1;
if (num >= n)
break;
sum += num;
num += 2;
if (num >= n)
break;
sum += num;
num += 3;
if (num >= n)
break;
sum += num;
}
printf("%d\n", sum);
return 0;
}

View File

@ -1,34 +0,0 @@
/**
* \file
* \brief [Problem 1](https://projecteuler.net/problem=1) solution
*
* An Efficient code to print all the sum of all numbers that are multiples of 3
* & 5 below N.
*/
#include <stdio.h>
/** Main function */
int main()
{
int t;
printf("Enter number of times you want to try");
scanf("%d", &t);
while (t--)
{
unsigned long long N, p = 0, sum = 0;
printf("Enter the value of N ");
scanf("%lld", &N); // Take input of N from user
for (int i = 0; i < N; i++)
{
if (i % 3 == 0 || i % 5 == 0)
{
sum = sum + i;
}
}
printf("%lld\n", sum); // print the sum of all numbers that are
// multiples of 3 & 5 below N
}
return 0;
}

View File

@ -1,43 +0,0 @@
/**
* \file
* \brief [Problem 10](https://projecteuler.net/problem=10) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
/** Function to check if a number is prime */
char is_prime(unsigned long n)
{
for (unsigned long i = 2; i < sqrtl(n) + 1; i++)
if (n % i == 0)
return 0;
return 1;
}
/** Computes sum of prime numbers less than N */
unsigned long long sum_of_primes(unsigned long N)
{
unsigned long long sum = 2;
for (long i = 3; i < N; i += 2) /* skip even numbers */
if (is_prime(i))
sum += i;
return sum;
}
/** Main function */
int main(int argc, char *argv[])
{
unsigned long n = 100;
if (argc == 2) /* if command line argument is provided */
n = atol(argv[1]); /* use that as the upper limit */
printf("%ld: %llu\n", n, sum_of_primes(n));
return 0;
}

View File

@ -1,56 +0,0 @@
/**
* \file
* \brief [Problem 10](https://projecteuler.net/problem=10) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
/** Main function */
int main(int argc, char *argv[])
{
long n = 100;
long long sum = 0;
char *sieve = NULL;
if (argc == 2) /* if command line argument is provided */
n = atol(argv[1]); /* use that as the upper limit */
/* allocate memory for the sieve */
sieve = calloc(n, sizeof(*sieve));
if (!sieve)
{
perror("Unable to allocate memory!");
return -1;
}
/* build sieve of Eratosthenes
In the array,
* if i^th cell is '1', then 'i' is composite
* if i^th cell is '0', then 'i' is prime
*/
for (long i = 2; i < sqrtl(n); i++)
{
/* if i^th element is prime, mark all its multiples
as composites */
if (!sieve[i])
{
for (long j = i * i; j < n + 1; j += i)
{
sieve[j] = 1;
}
sum += i;
}
}
for (long i = sqrtl(n) + 1; i < n; i++)
if (!sieve[i])
sum += i;
free(sieve);
printf("%ld: %lld\n", n, sum);
return 0;
}

View File

@ -1,55 +0,0 @@
/**
* \file
* \brief [Problem 12](https://projecteuler.net/problem=12) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
/**
* Get number of divisors of a given number
*
* If \f$x = a \times b\f$, then both \f$a\f$ and \f$b\f$ are divisors of
* \f$x\f$. Since multiplication is commutative, we only need to search till a
* maximum of \f$a=b = a^2\f$ i.e., till \f$\sqrt{x}\f$. At every integer till
* then, there are eaxctly 2 divisors and at \f$a=b\f$, there is only one
* divisor.
*/
long count_divisors(long long n)
{
long num_divisors = 0;
for (long long i = 1; i < sqrtl(n) + 1; i++)
if (n % i == 0)
num_divisors += 2;
else if (i * i == n)
num_divisors += 1;
return num_divisors;
}
/** Main function */
int main(int argc, char **argv)
{
int MAX_DIVISORS = 500;
long i = 1, num_divisors;
long long triangle_number = 1;
if (argc == 2)
MAX_DIVISORS = atoi(argv[1]);
while (1)
{
i++;
triangle_number += i;
num_divisors = count_divisors(triangle_number);
if (num_divisors > MAX_DIVISORS)
break;
}
printf("First Triangle number with more than %d divisors: %lld\n",
MAX_DIVISORS, triangle_number);
return 0;
}

View File

@ -1,100 +0,0 @@
37107287533902102798797998220837590246510135740250
46376937677490009712648124896970078050417018260538
74324986199524741059474233309513058123726617309629
91942213363574161572522430563301811072406154908250
23067588207539346171171980310421047513778063246676
89261670696623633820136378418383684178734361726757
28112879812849979408065481931592621691275889832738
44274228917432520321923589422876796487670272189318
47451445736001306439091167216856844588711603153276
70386486105843025439939619828917593665686757934951
62176457141856560629502157223196586755079324193331
64906352462741904929101432445813822663347944758178
92575867718337217661963751590579239728245598838407
58203565325359399008402633568948830189458628227828
80181199384826282014278194139940567587151170094390
35398664372827112653829987240784473053190104293586
86515506006295864861532075273371959191420517255829
71693888707715466499115593487603532921714970056938
54370070576826684624621495650076471787294438377604
53282654108756828443191190634694037855217779295145
36123272525000296071075082563815656710885258350721
45876576172410976447339110607218265236877223636045
17423706905851860660448207621209813287860733969412
81142660418086830619328460811191061556940512689692
51934325451728388641918047049293215058642563049483
62467221648435076201727918039944693004732956340691
15732444386908125794514089057706229429197107928209
55037687525678773091862540744969844508330393682126
18336384825330154686196124348767681297534375946515
80386287592878490201521685554828717201219257766954
78182833757993103614740356856449095527097864797581
16726320100436897842553539920931837441497806860984
48403098129077791799088218795327364475675590848030
87086987551392711854517078544161852424320693150332
59959406895756536782107074926966537676326235447210
69793950679652694742597709739166693763042633987085
41052684708299085211399427365734116182760315001271
65378607361501080857009149939512557028198746004375
35829035317434717326932123578154982629742552737307
94953759765105305946966067683156574377167401875275
88902802571733229619176668713819931811048770190271
25267680276078003013678680992525463401061632866526
36270218540497705585629946580636237993140746255962
24074486908231174977792365466257246923322810917141
91430288197103288597806669760892938638285025333403
34413065578016127815921815005561868836468420090470
23053081172816430487623791969842487255036638784583
11487696932154902810424020138335124462181441773470
63783299490636259666498587618221225225512486764533
67720186971698544312419572409913959008952310058822
95548255300263520781532296796249481641953868218774
76085327132285723110424803456124867697064507995236
37774242535411291684276865538926205024910326572967
23701913275725675285653248258265463092207058596522
29798860272258331913126375147341994889534765745501
18495701454879288984856827726077713721403798879715
38298203783031473527721580348144513491373226651381
34829543829199918180278916522431027392251122869539
40957953066405232632538044100059654939159879593635
29746152185502371307642255121183693803580388584903
41698116222072977186158236678424689157993532961922
62467957194401269043877107275048102390895523597457
23189706772547915061505504953922979530901129967519
86188088225875314529584099251203829009407770775672
11306739708304724483816533873502340845647058077308
82959174767140363198008187129011875491310547126581
97623331044818386269515456334926366572897563400500
42846280183517070527831839425882145521227251250327
55121603546981200581762165212827652751691296897789
32238195734329339946437501907836945765883352399886
75506164965184775180738168837861091527357929701337
62177842752192623401942399639168044983993173312731
32924185707147349566916674687634660915035914677504
99518671430235219628894890102423325116913619626622
73267460800591547471830798392868535206946944540724
76841822524674417161514036427982273348055556214818
97142617910342598647204516893989422179826088076852
87783646182799346313767754307809363333018982642090
10848802521674670883215120185883543223812876952786
71329612474782464538636993009049310363619763878039
62184073572399794223406235393808339651327408011116
66627891981488087797941876876144230030984490851411
60661826293682836764744779239180335110989069790714
85786944089552990653640447425576083659976645795096
66024396409905389607120198219976047599490197230297
64913982680032973156037120041377903785566085089252
16730939319872750275468906903707539413042652315011
94809377245048795150954100921645863754710598436791
78639167021187492431995700641917969777599028300699
15368713711936614952811305876380278410754449733078
40789923115535562561142322423255033685442488917353
44889911501440648020369068063960672322193204149535
41503128880339536053299340368006977710650566631954
81234880673210146739058568557934581403627822703280
82616570773948327592232845941706525094512325230608
22918802058777319719839450180888072429661980811197
77158542502016545090413245809786882778948721859617
72107838435069186155435662884062257473692284509516
20849603980134001723930671666823555245252804609722
53503534226472524250874054075591789781264330331690

View File

@ -1,172 +0,0 @@
/**
* \file
* \brief [Problem 13](https://projecteuler.net/problem=13) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/** Function to read the number from a file and store it in array.
\n index 0 of output buffer => units place
\n index 1 of output buffer => tens place and so on
i.e., index i => 10^i th place
*/
int get_number(FILE *fp, char *buffer, uint8_t *out_int)
{
long l = fscanf(fp, "%s\n", buffer);
if (!l)
{
perror("Error reading line.");
return -1;
}
// printf("Number: %s\t length: %ld, %ld\n", buffer, strlen(buffer), l);
long L = strlen(buffer);
for (int i = 0; i < L; i++)
{
if (buffer[i] < 0x30 || buffer[i] > 0x39)
{
perror("found inavlid character in the number!");
return -1;
}
else
{
out_int[L - i - 1] = buffer[i] - 0x30;
}
}
return 0;
}
/**
* Function to add arbitrary length decimal integers stored in an array.
* a + b = c = new b
*/
int add_numbers(uint8_t *a, uint8_t *b, uint8_t N)
{
int carry = 0;
uint8_t *c = b; /* accumulate the result in the array 'b' */
for (int i = 0; i < N; i++)
{
// printf("\t%d + %d + %d ", a[i], b[i], carry);
c[i] = carry + a[i] + b[i]; // NOLINT // This is a known false-positive
if (c[i] > 9) /* check for carry */
{
carry = 1;
c[i] -= 10;
}
else
{
carry = 0;
}
// printf("= %d, %d\n", carry, c[i]);
}
for (int i = N; i < N + 10; i++)
{
if (carry == 0)
{
break;
}
// printf("\t0 + %d + %d ", b[i], carry);
c[i] = carry + c[i];
if (c[i] > 9)
{
carry = 1;
c[i] -= 10;
}
else
{
carry = 0;
}
// printf("= %d, %d\n", carry, c[i]);
}
return 0;
}
/** Function to print a long number */
int print_number(uint8_t *number, uint8_t N, int8_t num_digits_to_print)
{
uint8_t start_pos = N - 1;
uint8_t end_pos;
/* skip all initial zeros */
while (number[start_pos] == 0) start_pos--;
/* if end_pos < 0, print all digits */
if (num_digits_to_print < 0)
{
end_pos = 0;
}
else if (num_digits_to_print <= start_pos)
{
end_pos = start_pos - num_digits_to_print + 1;
}
else
{
fprintf(stderr, "invalid number of digits argumet!\n");
return -1;
}
for (int i = start_pos; i >= end_pos; i--) putchar(number[i] + 0x30);
putchar('\n');
return 0;
}
/** Main function */
int main(void)
{
/* number of digits of the large number */
const int N = 10;
/* number of digits in output number */
const int N2 = N + 10;
// const char N = 50, N2 = N+10; /* length of numbers */
char *txt_buffer =
(char *)calloc(N + 5, sizeof(char)); /* temporary buffer */
uint8_t *number = (uint8_t *)calloc(
N, sizeof(uint8_t)); /* array to store digits of a large number */
uint8_t *sum = (uint8_t *)calloc(
N2, sizeof(uint8_t)); /* array to store the sum of the large
numbers. For safety, we make it twice the length of a number. */
FILE *fp = fopen("num.txt", "rt"); /* open text file to read */
if (!fp)
{
perror("Unable to open file 'num.txt'.");
free(txt_buffer);
free(sum);
free(number);
return -1;
}
int count = 0;
get_number(fp, txt_buffer, sum); /* 0 + = first_number = first_number */
do
{
count++;
if (get_number(fp, txt_buffer, number) != 0)
{
break;
}
add_numbers(number, sum, N);
} while (!feof(fp));
printf("\nSum : ");
print_number(sum, N2, -1);
printf("first 10 digits: \t");
print_number(sum, N2, 10);
fclose(fp); /* close file */
free(txt_buffer);
free(sum);
free(number);
return 0;
}

View File

@ -1,79 +0,0 @@
/**
* \file
* \brief [Problem 14](https://projecteuler.net/problem=14) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*
* Since the computational values for each iteration step are independent,
* we can compute them in parallel. However, the maximum values should be
* updated in synchrony so that we do not get into a "race condition".
*
* To compile with supporintg gcc or clang, the flag "-fopenmp" should be
* passes while with Microsoft C compiler, the flag "/fopenmp" should be
* used. If you are using the provided CMAKE compilation, it will automatically
* detect OPENMP and compile with it for you.
*
* Automatically detects for OPENMP using the _OPENMP macro.
*/
#include <stdio.h>
#include <stdlib.h>
#ifdef _OPENMP
#include <omp.h>
#endif
/**
* Computes the length of collatz sequence for a given
* starting number
*/
long long collatz(long long start_num)
{
long long length = 1;
while (start_num != 1) /* loop till we reach 1 */
{
if (start_num & 0x01) /* check for odd */
start_num = 3 * start_num + 1;
else
start_num >>= 1; /* simpler divide by 2 */
length++;
}
return length;
}
/** Main function */
int main(int argc, char **argv)
{
long long max_len = 0, max_len_num = 0;
long long MAX_NUM = 1000000;
if (argc ==
2) /* set commandline argumnet as the maximum iteration number */
{
MAX_NUM = atoll(argv[1]);
printf("Maximum number: %lld\n", MAX_NUM);
}
long long i;
#ifdef _OPENMP
#pragma omp parallel for shared(max_len, max_len_num) schedule(guided)
#endif
for (i = 1; i < MAX_NUM; i++)
{
long long L = collatz(i);
if (L > max_len)
{
max_len = L; /* length of sequence */
max_len_num = i; /* starting number */
}
#if defined(_OPENMP) && defined(DEBUG)
printf("Thread: %2d\t %3lld: \t%5lld\n", omp_get_thread_num(), i, L);
#elif defined(DEBUG)
printf("%3lld: \t%5lld\n", i, L);
#endif
}
printf("Start: %3lld: \tLength: %5lld\n", max_len_num, max_len);
return 0;
}

View File

@ -1,41 +0,0 @@
/**
* \file
* \brief [Problem 15](https://projecteuler.net/problem=15) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/**
* At every node, there are 2 possible ways to move -> down or right.
* Since it is a square grid, there are in all, 2N steps with N down
* and N right options, without preference for order.
* Hence, the path can be be traced in N out of 2N number of ways.
* This is the same as binomial coeeficient.
*/
unsigned long long number_of_paths(int N)
{
unsigned long long path = 1;
for (int i = 0; i < N; i++)
{
path *= (N << 1) - i;
path /= i + 1;
}
return path;
}
/** Main function */
int main(int argc, char **argv)
{
int N = 20;
if (argc == 2)
N = atoi(argv[1]);
printf("Number of ways to traverse diagonal of %dx%d grid = %llu\n", N, N,
number_of_paths(N));
return 0;
}

View File

@ -1,62 +0,0 @@
/**
* \file
* \brief [Problem 16](https://projecteuler.net/problem=16) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/** Main function */
int main(int argc, char **argv)
{
const double tmp = log(10) / log(2); /* required to get number of digits */
unsigned long MAX_NUM_DIGITS;
uint8_t *digits =
NULL; /* array to store individual digits. index 0 = units place */
int N = 1000, sum = 0;
if (argc == 2)
N = atoi(argv[1]);
MAX_NUM_DIGITS = (N + tmp) / tmp;
digits = calloc(MAX_NUM_DIGITS, sizeof(uint8_t));
digits[0] = 1;
if (!digits)
{
perror("Unable to allocate memory!");
return -1;
}
for (int i = 0; i < N; i++)
{
int carry = 0;
for (int j = 0; j < MAX_NUM_DIGITS; j++)
{
digits[j] = (digits[j] << 1) + carry; /* digit * 2 + carry */
// printf("\t value: %d\t", digits[j]);
if (digits[j] > 9)
{
carry = 1;
digits[j] -= 10;
}
else
carry = 0;
// printf("carry: %d\t value: %d\n", carry, digits[j]);
/* accumulate sum for last multiplication */
if (i == N - 1)
sum += digits[j];
}
}
printf("2^%d = ", N);
for (int i = MAX_NUM_DIGITS - 1; i >= 0; i--) putchar(digits[i] + 0x30);
printf("\n\t Sum: %d\t Num. digits: %lu\n", sum, MAX_NUM_DIGITS);
free(digits);
return 0;
}

View File

@ -1,135 +0,0 @@
/**
* \file
* \brief [Problem 19](https://projecteuler.net/problem=19) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <stdio.h>
/**
* Function to get the number of days in a month.
* \param month month identified by an integer -\n
* > 0 = Jan and 11 = December
* \returns number of days in given month
* \note For February, adjust for leap year outside the function.
*/
char get_month_days(short month)
{
if (month == 1) /* February has 28 days. Adjust leap year in the loop */
return 28;
else if (month <= 6) /* odd months till July have 30 days - Jan = 0 (even)*/
{
if (month & 0x01)
return 30;
else
return 31;
}
// else if (month >= 7) /* odd months after July have 31 days*/
if (month & 0x01)
return 31;
return 30;
}
/**
* @brief Check if input year is a leap year.
* \param year year to check
* \return 1 if input year is a leap year
* \return 0 if input year is not a leap year
*/
char is_leap_year(short year)
{
if ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)))
return 1;
return 0;
}
#ifdef DEBUG
/** Function to convert integer month to string
* \param day integer identifier of day (0 = Sunday and 7 = Saturday
* \return pointer to string representation)
*/
const char *day_string(int day)
{
switch (day)
{
case 0:
return "Sunday";
case 1:
return "Monday";
case 2:
return "Tuesday";
case 3:
return "Wednesday";
case 4:
return "Thursday";
case 5:
return "Friday";
case 6:
return "Saturday";
default:
return "Shouldn't see this!";
}
}
#endif
/** Main function */
int main(int argc, char **argv)
{
int count_sundays = 0;
const short start_year = 1901;
const short end_year = 2000;
/*
* Let us identify days i.e., Sunday thru Saturday with integers - 0 thru 6
* respectively Jan 1 1901 was a Tuesday
*/
char start_day = 2;
for (int year = start_year; year <= end_year; year++)
{
char is_leap = is_leap_year(year);
for (char month = 0; month < 12; month++)
{
/*
* These two for-loops count the start of day for the next month.
* Hence, we have to skip the last December count
*/
if (year == end_year && month == 11)
continue;
int days = get_month_days(month);
if (is_leap && month == 1) /* for a leap year february, add a day */
days++;
#ifdef DEBUG
if (year == end_year)
{
printf("Year: %d\t Month: %d\t Days: %d\t First of day: %s\n",
year, month, days, day_string(start_day));
}
#endif
/* Main Algorithm:
* every week has 7 days hence, the start of next day would be
* modulo 7 add to this, the current start date and ensure the
* result is still modulo 7!
*/
start_day = ((days % 7) + start_day) % 7;
/* If start-day is a Sunday, increment counter */
if (start_day == 0)
count_sundays++;
}
}
printf(
"Total number of Sundays that happened on the 1st of a month in the "
"last century: %d\n",
count_sundays);
return 0;
}

View File

@ -1,37 +0,0 @@
/**
* \file
* \brief [Problem 2](https://projecteuler.net/problem=2) solution
*
* Problem:
*
* Each new term in the Fibonacci sequence is generated by adding the previous
* two terms. By starting with 1 and 2, the first 10 terms will be:
* `1,2,3,5,8,13,21,34,55,89,..`
* By considering the terms in the Fibonacci sequence whose values do not exceed
* n, find the sum of the even-valued terms. e.g. for n=10, we have {2,8}, sum
* is 10.
*/
#include <stdio.h>
/** Main function */
int main()
{
int n = 0;
int sum = 0;
int i = 1;
int j = 2;
int temp;
scanf("%d", &n);
while (j <= n)
{
if ((j & 1) == 0) // can also use(j%2 == 0)
sum += j;
temp = i;
i = j;
j = temp + i;
}
printf("%d\n", sum);
return 0;
}

View File

@ -1,183 +0,0 @@
/**
* \file
* \brief [Problem 20](https://projecteuler.net/problem=20) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*
* Implementation uses a custom `big_int` structure that can store arbitrarily
* large integer numbers.
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/**
* store arbitratily large integer values
* as a linked list of digits.
*/
typedef struct _big_int
{
char value; /**< tens place (single digit) */
struct _big_int *next_digit; /**< hundreds place */
struct _big_int *prev_digit; /**< units place */
} big_int;
#ifdef DEBUG
/** print a digit from large integer */
void print_digit(const big_int *my_int)
{
printf("\tValue : %d\n\tNext : %p\n\tPrev : %p\n", my_int->value,
my_int->next_digit, my_int->prev_digit);
}
#endif
/**
* Function that allocates memory to add another
* digit at the MSB
*/
big_int *add_digit(big_int *digit, char value)
{
if (digit == NULL)
{
digit = (big_int *)malloc(sizeof(big_int));
if (!digit)
{
perror("Unable to allocate memory!");
return NULL;
}
digit->value = value;
digit->next_digit = NULL;
digit->prev_digit = NULL;
return digit;
}
if (digit->next_digit)
{
digit->next_digit->value = value;
return digit->next_digit;
}
digit->next_digit = (big_int *)malloc(sizeof(big_int));
if (digit->next_digit == NULL)
{
perror("Unable to allocate memory!");
return NULL;
}
digit->next_digit->value = value;
digit->next_digit->next_digit = NULL;
digit->next_digit->prev_digit = digit;
return digit->next_digit;
}
/**
* Function to remove digits preceeding the
* current digit.
*/
char remove_digits(big_int *digit, int N)
{
if (digit == NULL)
return 0;
if (digit->next_digit == NULL)
{
free(digit);
digit = NULL;
return 0;
}
if (N > 0)
return remove_digits(digit->next_digit, N - 1);
return remove_digits(digit->next_digit, 0);
}
/** Main function */
int main(int argc, char **argv)
{
unsigned int N = 5;
big_int *ptr = add_digit(NULL, 1); /* start with 1 */
const big_int *ptr0 = ptr; /* save the first location */
unsigned long sum_digits = 0;
unsigned long num_digits = 0;
if (argc == 2)
N = atoi(argv[1]);
clock_t start_time = clock();
for (unsigned int i = 1; i <= N; i++)
{
int carry = 0;
#ifdef DEBUG
printf("%3d: ", i);
#endif
ptr = (big_int *)ptr0; /* multiply every digit with i */
while (ptr)
{
#ifdef DEBUG
printf("%p\t", ptr);
#endif
unsigned int tmp = ptr->value * i + carry;
if (tmp >= 10)
{
div_t tmp2 = div(tmp, 10);
carry = tmp2.quot;
tmp = tmp2.rem;
}
else
carry = 0;
if (carry > 0 && ptr->next_digit == NULL)
add_digit(ptr, 0);
ptr->value = tmp;
if (i == N)
/*
* sum digits on the last iteration
* this avoid having another loop over all digits
*/
sum_digits += tmp;
if (ptr->next_digit)
/* more digits available */
ptr = ptr->next_digit;
else
/* no more digits left - reached MSB */
break;
}
#ifdef DEBUG
printf("\n");
#endif
}
clock_t end_time = clock();
#ifdef DEBUG
printf("ptr = %p\n", ptr);
printf("%d! = ", N);
#endif
/* Notice that in the loop above, we make sure that at the end of the loop,
* ptr is pointing to the last digit. Thus we can avoid using another loop.
*/
// ptr = &my_int;
// /* move ptr to the MSB digit */
// while (ptr->next_digit)
// ptr = ptr->next_digit;
do
{
putchar(ptr->value + 0x30); /* convert digit to ASCII char */
ptr = ptr->prev_digit;
num_digits++;
} while (ptr); /* after coming to units place, there will be no valid ptr */
printf("\nTime taken: %.4g millisecond\n",
1e3 * (end_time - start_time) / CLOCKS_PER_SEC);
printf(
"Digit Sum = %lu\tNumber of digits = %lu\tStorage space = %.3gkb\t \n",
sum_digits, num_digits, num_digits * sizeof(big_int) / 1024.0);
remove_digits((big_int *)ptr0, -1);
return 0;
}

View File

@ -1,93 +0,0 @@
/**
* \file
* \brief [Problem 21](https://projecteuler.net/problem=21) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/**
* function to return the sum of proper divisors of N
*/
unsigned long sum_of_divisors(unsigned int N)
{
unsigned long sum = 1 + N; /* 1 and itself are always a divisor */
/* divisors are symmertically distributed about the square-root */
for (unsigned int i = 2; i * i < N; i++)
{
if ((N % i) != 0)
/* i is not a divisor of N */
continue;
// #ifdef DEBUG
// printf("%4d, %4d,", i, N / i);
// #endif
sum += i + (N / i);
}
// #ifdef DEBUG
// printf("\nSum of divisors of %4d: %4d\n", N, sum);
// #endif
return sum;
}
/** Main function */
int main(int argc, char **argv)
{
unsigned long sum = 0;
unsigned int MAX_N = 500;
if (argc == 2)
MAX_N = atoi(argv[1]);
/*
* We use an array of flags to check if a number at the index was:
* not-processed = 0
* is amicable = 1
* not amicable = -1
*/
char *flags = (char *)calloc(MAX_N, sizeof(char));
clock_t start_time = clock();
int i;
/* there are no such numbers till 10. Lets search from there on */
for (i = 10; i < MAX_N; i++)
{
if (flags[i] != 0)
/* already processed, skip */
continue;
unsigned int b = sum_of_divisors(i);
if (b >= MAX_N)
flags[i] = -1;
else if (flags[b] == -1)
continue;
unsigned int c = sum_of_divisors(b);
if (c == i && b != i)
{
/* found amicable */
flags[b] = 1;
flags[i] = 1;
sum += b + i;
#ifdef DEBUG
printf("Amicable: %4d : %4d\n", i, b);
#endif
}
else
{
flags[i] = -1;
if (b < MAX_N)
flags[b] = -1;
}
}
clock_t end_time = clock();
printf("\nTime taken: %.4g millisecond\n",
1e3 * (end_time - start_time) / CLOCKS_PER_SEC);
printf("Sum of all numbers = %lu\n", sum);
free(flags);
return 0;
}

File diff suppressed because one or more lines are too long

View File

@ -1,149 +0,0 @@
/**
* \file
* \brief [Problem 22](https://projecteuler.net/problem=22) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef _OPENMP
#include <omp.h>
#endif
#define MAX_NAMES 6000 /**< Maximum number of names to store */
#define MAX_NAME_LEN 20 /**< Maximum length of each name */
/**
* Alphabetical sorting using 'shell sort' algorithm
*/
void shell_sort(char data[][MAX_NAME_LEN], int LEN)
{
const int gaps[] = {701, 301, 132, 57, 23, 10, 4, 1};
const int gap_len = 8;
int i, j, g;
for (g = 0; g < gap_len; g++)
{
int gap = gaps[g];
for (i = gap; i < LEN; i++)
{
char tmp_buffer[MAX_NAME_LEN];
strcpy(tmp_buffer, data[i]);
for (j = i; j >= gap && strcmp(data[j - gap], tmp_buffer) > 0;
j -= gap)
strcpy(data[j], data[j - gap]);
strcpy(data[j], tmp_buffer);
}
}
#ifdef DEBUG
for (i = 0; i < LEN; i++) printf("%s\t", data[i]);
#endif
}
/**
* Alphabetical sorting using 'lazy sort' algorithm
*/
void lazy_sort(char data[][MAX_NAME_LEN], int LEN)
{
int i, j;
for (i = 0; i < LEN; i++)
{
for (j = i + 1; j < LEN; j++)
{
if (strcmp(data[i], data[j]) > 0)
{
char tmp_buffer[MAX_NAME_LEN];
strcpy(tmp_buffer, data[i]);
strcpy(data[i], data[j]);
strcpy(data[j], tmp_buffer);
}
}
}
#ifdef DEBUG
for (i = 0; i < LEN; i++) printf("%s\t", data[i]);
#endif
}
/** Main function */
int main(int argc, char **argv)
{
unsigned long COUNT = 0;
char *fname = "names.txt";
char names[MAX_NAMES][MAX_NAME_LEN];
short method = 0; /* sorting algorithm to use. 0 = lazy, 1 = shell-sort */
if (argc == 2)
method = atoi(argv[1]);
FILE *fp = fopen(fname, "rt");
if (!fp)
{
perror("Unable to open file");
return -1;
}
/*
* Loops to get total number of rows and columns in the file
*/
do
{
int ret = fscanf(fp, "\"%[^\",]\",", names[COUNT++]);
if (ret <= 0)
continue;
// printf("%s\t", names[COUNT - 1]);
} while (!feof(fp));
fclose(fp);
printf("\nTotal number of names: %lu\n", COUNT);
if (method == 0)
{
clock_t start_time = clock();
shell_sort(names, COUNT);
clock_t end_time = clock();
printf("\nShell sort: %.4g millisecond\n",
1e3 * (end_time - start_time) / CLOCKS_PER_SEC);
}
else if (method == 1)
{
clock_t start_time = clock();
lazy_sort(names, COUNT);
clock_t end_time = clock();
printf("\nLazy sort: %.4g millisecond\n",
1e3 * (end_time - start_time) / CLOCKS_PER_SEC);
}
long sum_score = 0;
clock_t start_time = clock();
int i;
#ifdef _OPENMP
#pragma omp parallel for schedule(runtime) reduction(+ : sum_score)
#endif
#ifdef DEBUG
for (i = 935; i < 940; i++)
#else
for (i = 0; i < COUNT; i++)
#endif
{
long score = 0;
/* score the alphabets in i^th name */
for (int j = 0; names[i][j] != '\0'; j++)
score += names[i][j] - 'A' +
1; /* convert ASCII character to integer score */
sum_score += score * (i + 1);
#ifdef DEBUG
printf("Name: %s\tScore: %u x %u = %lu\n", names[i], score, i + 1,
(unsigned long)score * (i + 1));
#endif
}
clock_t end_time = clock();
printf("Scoring time: %.4g millisecond\n",
1e3 * (end_time - start_time) / CLOCKS_PER_SEC);
printf("Total Score = %lu\n", sum_score);
return 0;
}

View File

@ -1,138 +0,0 @@
/**
* \file
* \brief [Problem 23](https://projecteuler.net/problem=23) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef _OPENMP
#include <omp.h>
#endif
/**
* Returns:
* -1 if N is deficient
* 1 if N is abundant
* 0 if N is perfect
*/
char get_perfect_number(unsigned long N)
{
unsigned long sum = 1;
char ret = 0;
for (unsigned long i = 2; i * i <= N; i++)
{
if (N % i == 0)
{
sum += i;
unsigned long tmp = N / i;
if (tmp != i)
{
sum += tmp;
}
}
}
ret = sum == N ? 0 : (sum > N ? 1 : -1);
// #ifdef DEBUG
// printf("%5lu: %5lu : %d\n", N, sum, ret);
// #endif
return ret;
}
/**
* Is the given number an abundant number (1) or not (0)
*/
unsigned long is_abundant(unsigned long N)
{
return get_perfect_number(N) == 1 ? 1 : 0;
}
/**
* Find the next abundant number after N and not including N
*/
unsigned long get_next_abundant(unsigned long N)
{
unsigned long i;
for (i = N + 1; !is_abundant(i); i++)
{
;
}
return i;
}
/**
* check if a given number can be represented as a sum
* of two abundant numbers.
* \returns 1 - if yes
* \returns 0 - if not
*/
char is_sum_of_abundant(unsigned long N)
{
/* optimized logic:
* i + j = N where both i and j should be abundant
* hence we can simply check for j = N - i as we loop through i
*/
for (unsigned long i = get_next_abundant(1); i <= (N >> 1);
i = get_next_abundant(i))
{
if (is_abundant(N - i))
{
#ifdef DEBUG
printf("\t%4lu + %4lu = %4lu\n", i, N - i, N);
#endif
return 1;
}
}
return 0;
}
/** Main function */
int main(int argc, char **argv)
{
unsigned long MAX_N = 28123; /* upper limit of numbers to check */
unsigned long sum = 0;
if (argc == 2)
{
MAX_N = strtoul(argv[1], NULL, 10);
}
#ifdef _OPENMP
printf("Using OpenMP parallleization with %d threads\n",
omp_get_max_threads());
#else
printf("Not using parallleization!\n");
#endif
double total_duration = 0.f;
long i;
#ifdef _OPENMP
#pragma omp parallel for reduction(+ : sum) schedule(runtime)
#endif
for (i = 1; i <= MAX_N; i++)
{
clock_t start_time = clock();
if (!is_sum_of_abundant(i))
{
sum += i;
}
clock_t end_time = clock();
total_duration += (double)(end_time - start_time) / CLOCKS_PER_SEC;
printf("... %5lu: %8lu\r", i, sum);
if (i % 100 == 0)
{
fflush(stdout);
}
}
printf("Time taken: %.4g s\n", total_duration);
printf(
"Sum of numbers that cannot be represented as sum of two abundant "
"numbers : %lu\n",
sum);
return 0;
}

View File

@ -1,205 +0,0 @@
/**
* \file
* \brief [Problem 23](https://projecteuler.net/problem=23) solution -
* optimization using look-up array
* \author [Krishna Vedala](https://github.com/kvedala)
*
* Optimization applied - compute & store abundant numbers once
* into a look-up array.
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef _OPENMP
#include <omp.h>
#endif
/**
* This is the global array to be used to store a flag to identify
* if a particular number is abundant (1) or not (0).
* Using a whole byte to store a binary info would be redundant.
* We will use each byte to represent 8 numbers by relying on bits.
* This saves memory required by 1/8
*/
char *abundant_flags = NULL;
/**
* \returns -1 if N is deficient
* \returns 1 if N is abundant
* \returns 0 if N is perfect
*/
char get_perfect_number(unsigned long N)
{
unsigned long sum = 1;
char ret = 0;
for (unsigned long i = 2; i * i <= N; i++)
{
if (N % i == 0)
{
sum += i;
unsigned long tmp = N / i;
if (tmp != i)
{
sum += tmp;
}
}
}
ret = sum == N ? 0 : (sum > N ? 1 : -1);
#ifdef DEBUG
printf("%5lu: %5lu : %d\n", N, sum, ret);
#endif
return ret;
}
/**
* Is the given number an abundant number (1) or not (0)
*/
char is_abundant(unsigned long N)
{
// return abundant_flags[N >> 3] & (1 << N % 8) ? 1 : 0;
return abundant_flags[N >> 3] & (1 << (N & 7))
? 1
: 0; /* optimized modulo operation */
}
/**
* Find the next abundant number after N and not including N
*/
unsigned long get_next_abundant(unsigned long N)
{
unsigned long i;
/* keep checking successive numbers till an abundant number is found */
for (i = N + 1; !is_abundant(i); ++i)
{
;
}
return i;
}
/**
* check if a given number can be represented as a sum
* of two abundant numbers.
* \returns 1 - if yes
* \returns 0 - if not
*/
char is_sum_of_abundant(unsigned long N)
{
/* optimized logic:
* i + j = N where both i and j should be abundant
* hence we can simply check for j = N - i as we loop through i
*/
for (unsigned long i = get_next_abundant(1); i <= (N >> 1);
i = get_next_abundant(i))
{
if (is_abundant(N - i))
{
#ifdef DEBUG
printf("\t%4lu + %4lu = %4lu\n", i, N - i, N);
#endif
return 1;
}
}
return 0;
}
/** Main function */
int main(int argc, char **argv)
{
long MAX_N = 28123; /* Limit of numbers to check */
unsigned long sum = 0;
if (argc == 2)
{
MAX_N = strtoul(argv[1], NULL, 10);
}
/* byte array to store flags to identify abundant numbers
* the flags are identified by bits
*/
abundant_flags = (char *)calloc(MAX_N >> 3, 1);
if (!abundant_flags)
{
perror("Unable to allocate memoey!");
return -1;
}
#ifdef _OPENMP
printf("Using OpenMP parallleization with %d threads\n",
omp_get_max_threads());
#else
printf("Not using parallleization!\n");
#endif
clock_t start_time = clock();
/* Loop to set abundant flags */
long N;
#ifdef _OPENMP
#pragma omp for schedule(runtime)
#endif
for (N = 1; N <= MAX_N; N++)
{
char ret = get_perfect_number(N);
if (ret == 1)
{
// int byte_offset = N % 8, index = N >> 3;
int byte_offset = N & 7, index = N >> 3;
#ifdef _OPENMP
#pragma omp critical
#endif
abundant_flags[index] |= ret << byte_offset;
}
// if (i % 100 == 0)
// printf("... %5lu: %8lu\r", i, sum);
}
clock_t end_time = clock();
double t1 = 1e3 * (end_time - start_time) / CLOCKS_PER_SEC;
printf("Time taken to get abundant numbers: %.4g ms\n", t1);
clock_t t2 = 0;
long i;
#ifdef _OPENMP
#pragma omp parallel for schedule(runtime) reduction(+ : sum)
#endif
for (i = 1; i < MAX_N; i++)
{
clock_t start_time1 = clock();
if (!is_sum_of_abundant(i))
{
// #ifdef _OPENMP
// #pragma omp critical
// #endif
sum += i;
}
clock_t end_time1 = clock();
#ifdef _OPENMP
#pragma omp critical
#endif
t2 += end_time1 - start_time1;
printf("... %5lu: %8lu\r", i, sum);
if (i % 100 == 0)
{
fflush(stdout);
}
}
#ifdef DEBUG
putchar('\n');
#endif
double t22 = 1e3 * t2 / CLOCKS_PER_SEC;
printf("Time taken for final sum: %.4g ms\nTotal Time taken: %.4g ms\n",
t22, t1 + t22);
printf("Memory used: %lu bytes\n", MAX_N >> 3);
printf(
"Sum of numbers that cannot be represented as sum of two abundant "
"numbers : %lu\n",
sum);
free(abundant_flags);
return 0;
}

Binary file not shown.

View File

@ -1,125 +0,0 @@
/**
* \file
* \brief [Problem 25](https://projecteuler.net/problem=25) solution implemented
* using arbitrarily large numbers represented as arrays
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX_DIGITS 1000 /**< maximum number of digits */
/**
* Function to add arbitraty length decimal integers stored in an array.\n
* a + b = c = new b
*/
unsigned int add_numbers(unsigned char *a, unsigned char *b, unsigned char *c,
int N)
{
unsigned char carry = 0;
unsigned int i;
for (i = 0; i < N; i++)
{
// printf("\t%d + %d + %d ", a[i], b[i], carry);
c[i] = carry + a[i] + b[i];
if (c[i] > 9) /* check for carry */
{
carry = 1;
c[i] -= 10;
}
else
{
carry = 0;
}
// printf("= %d, %d\n", carry, c[i]);
}
while (carry != 0)
{
// printf("\t\t...adding new digit\n");
// printf("\t0 + %d + %d ", b[i], carry);
c[i] = carry + c[i];
if (c[i] > 9)
{
carry = 1;
c[i] -= 10;
}
else
{
carry = 0;
}
// printf("= %d, %d\n", carry, c[i]);
i++;
}
return i;
}
/** Print a large number */
int print_number(unsigned char *number, int N)
{
int start_pos = N - 1;
/* skip all initial zeros */
while (number[start_pos] == 0) start_pos--;
for (int i = start_pos; i >= 0; i--) putchar(number[i] + 0x30);
return 0;
}
/** Get number of digits in a large number */
unsigned int get_digits(unsigned char *number)
{
unsigned int digits = MAX_DIGITS;
while (number[digits] == 0) digits--;
return digits;
}
/** Main function */
int main(int argc, char *argv[])
{
unsigned char
fn[MAX_DIGITS + 1]; /* array to store digits of a large number */
unsigned char fn1[MAX_DIGITS + 1];
unsigned char sum[MAX_DIGITS + 1];
memset(fn, 0, MAX_DIGITS);
memset(fn1, 0, MAX_DIGITS);
memset(sum, 0, MAX_DIGITS);
fn[0] = 1;
fn1[1] = 1;
unsigned int index = 1, digit_count = 1;
clock_t start_time = clock();
do
{
digit_count = add_numbers(fn, fn1, sum, digit_count);
// digit_count = get_digits(sum);
// printf("%5u (%u) (%u) ", index, digit_count, get_digits(sum));
// print_number(sum, digit_count);
// putchar('\n');
if (digit_count == MAX_DIGITS)
{
break;
}
memcpy(fn, fn1, MAX_DIGITS);
memcpy(fn1, sum, MAX_DIGITS);
index++;
} while (digit_count < MAX_DIGITS);
clock_t end_time = clock();
printf("Time taken: %.4g ms\n",
1e3 * (end_time - start_time) / CLOCKS_PER_SEC);
printf("The nth term for %d digits: %u \n", MAX_DIGITS, index--);
print_number(sum, digit_count);
return 0;
}

View File

@ -1,88 +0,0 @@
/**
* \file
* \brief [Problem 26](https://projecteuler.net/problem=26) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef _OPENMP
#include <omp.h>
#endif
#define MAX_DENO 2000 /**< limit of unit fractions */
#define MAX_LEN \
(MAX_DENO + 10) /**< length of resulting recurring fraction number */
/** comparison function for use with internal `qsort` algorithm */
int compare(const void *a, const void *b)
{
return (*(unsigned short *)a - *(unsigned short *)b);
}
/** Main function */
int main(int argc, char *argv[])
{
unsigned short max_digits = 0, max_idx_number = 0;
clock_t start_time = clock();
short deno;
#ifdef _OPENMP
#pragma omp for
#endif
for (deno = 2; deno < MAX_DENO; deno++)
{
unsigned short remainders[MAX_LEN];
unsigned short rem = 1, *rem_ptr = remainders;
memset(remainders, (unsigned short)-1,
MAX_LEN * sizeof(unsigned short));
// remainders[0] = 1;
// printf("1/%-4u\t ", deno);
unsigned short index = 0, num_digits;
while (rem != 0)
{
rem = (rem * 10) % deno;
if (rem == 0)
{
index = 0;
break;
}
rem_ptr = (unsigned short *)bsearch(
&rem, remainders, MAX_LEN, sizeof(unsigned short), compare);
// printf("%2d, ", rem);
// printf("(%14p), ", rem_ptr);
if (rem_ptr != NULL)
break;
remainders[index] = rem;
rem_ptr = remainders;
index++;
}
num_digits = index - (rem_ptr - remainders);
// printf("\n\t(%14p, %14p, %4u, %4u)\n", rem_ptr, remainders, index,
// num_digits);
#ifdef _OPENMP
#pragma omp critical
{
#endif
if (num_digits > max_digits)
{
max_digits = num_digits;
max_idx_number = deno;
// printf("\t (%u, %u)\n ", max_digits, max_idx_number);
}
#ifdef _OPENMP
}
#endif
}
clock_t end_time = clock();
printf("Time taken: %.4g ms\n",
1e3 * (double)(end_time - start_time) / CLOCKS_PER_SEC);
printf("Maximum digits: %hu\t Denominator: %hu\n", max_digits,
max_idx_number);
return 0;
}

View File

@ -1,79 +0,0 @@
/**
* \file
* \brief [Problem 3](https://projecteuler.net/problem=3) solution
*
* Problem:
*
* The prime factors of 13195 are 5,7,13 and 29. What is the largest prime
* factor of a given number N? e.g. for 10, largest prime factor = 5. For 17,
* largest prime factor = 17.
*/
#include <math.h>
#include <stdio.h>
/** Check if the given number is prime */
char isprime(int no)
{
int sq;
if (no == 2)
{
return 1;
}
else if (no % 2 == 0)
{
return 0;
}
sq = ((int)(sqrt(no))) + 1;
for (int i = 3; i < sq; i += 2)
{
if (no % i == 0)
{
return 0;
}
}
return 1;
}
/** Main function */
int main()
{
int maxNumber = 0;
int n = 0;
int n1;
scanf("%d", &n);
if (isprime(n) == 1)
printf("%d", n);
else
{
while (n % 2 == 0)
{
n = n / 2;
}
if (isprime(n) == 1)
{
printf("%d\n", n);
}
else
{
n1 = ((int)(sqrt(n))) + 1;
for (int i = 3; i < n1; i += 2)
{
if (n % i == 0)
{
if (isprime((int)(n / i)) == 1)
{
maxNumber = n / i;
break;
}
else if (isprime(i) == 1)
{
maxNumber = i;
}
}
}
printf("%d\n", maxNumber);
}
}
return 0;
}

View File

@ -1,33 +0,0 @@
/**
* \file
* \brief [Problem 3](https://projecteuler.net/problem=3) solution
*
* Problem:
*
* The prime factors of 13195 are 5,7,13 and 29. What is the largest prime
* factor of a given number N? e.g. for 10, largest prime factor = 5. For 17,
* largest prime factor = 17.
*/
#include <stdio.h>
/** Main function */
int main()
{
int n = 0;
scanf("%d", &n);
int prime = 1;
int i = 2;
while (i * i <= n)
{
while (n % i == 0)
{
prime = i;
n /= i;
}
i += 1;
}
if (n > 1)
prime = n;
printf("%d\n", prime);
return 0;
}

View File

@ -1,41 +0,0 @@
/**
* \file
* \brief [Problem 4](https://projecteuler.net/problem=4) solution
*/
#include <stdio.h>
/** Check if number is palindromic
* \param[in] n number to check
* \returns 1 if palindromic
* \returns 0 if not palindromic
*/
int is_palindromic(unsigned int n)
{
unsigned int reversed = 0, t = n;
while (t > 0)
{
reversed = 10 * reversed + (t % 10);
t /= 10;
}
return reversed == n;
}
/** Main function */
int main(void)
{
unsigned int i, j, max = 0;
for (i = 100; i <= 999; i++)
{
for (j = 100; j <= 999; j++)
{
unsigned int p = i * j;
if (is_palindromic(p) && p > max)
{
max = p;
}
}
}
printf("%u\n", max);
return 0;
}

View File

@ -1,155 +0,0 @@
/**
* \file
* \brief [Problem 401](https://projecteuler.net/problem=401) solution -
* Sum of squares of divisors
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#ifdef _OPENMP
#include <omp.h>
#endif
#define MOD_LIMIT (uint64_t)1e9 /**< modulo limit */
#define MAX_LENGTH 5000 /**< chunk size of array allocation */
/**
* Check if a number is present in given array
* \param[in] N number to check
* \param[in] D array to check
* \param[in] L length of array
* \returns 1 if present
* \returns 0 if absent
*/
char is_in(uint64_t N, uint64_t *D, uint64_t L)
{
uint64_t i;
for (i = 0; i < L; i++)
{
if (D[i] == N)
{
return 1;
}
}
return 0;
}
/**
* Get all integer divisors of a number
* \param[in] N number to find divisors for
* \param[out] D array to store divisors in
* \returns number of divisors found
*/
uint64_t get_divisors(uint64_t N, uint64_t *D)
{
uint64_t q, r;
int64_t i, num = 0;
if (N == 1)
{
D[0] = 1;
return 1;
}
// search till sqrt(N)
// because after this, the pair of divisors will repeat themselves
for (i = 1; i * i <= N + 1; i++)
{
r = N % i; // get reminder
// reminder = 0 if 'i' is a divisor of 'N'
if (r == 0)
{
q = N / i;
if (!is_in(i, D, num)) // if divisor was already stored
{
D[num] = i;
num++;
}
if (!is_in(q, D, num)) // if divisor was already stored
{
D[num] = q;
num++;
}
}
if (num == MAX_LENGTH)
{ // limit of array reached, allocate more space
D = (uint64_t *)realloc(D, MAX_LENGTH * sizeof(uint64_t) << 1);
}
}
return num;
}
/**
* compute sum of squares of all integer factors of a number
* \param[in] N
* \returns sum of squares
*/
uint64_t sigma2(uint64_t N)
{
uint64_t sum = 0, L;
int64_t i;
uint64_t *D = (uint64_t *)malloc(MAX_LENGTH * sizeof(uint64_t));
L = get_divisors(N, D);
for (i = 1; i < L; i++)
{
uint64_t DD = (D[i] * D[i]) % MOD_LIMIT;
sum += DD;
}
free(D);
return sum % MOD_LIMIT;
}
/**
* sum of squares of factors of numbers
* from 1 thru N
*/
uint64_t sigma(uint64_t N)
{
uint64_t s, sum = 0;
int64_t i;
#ifdef _OPENMP
// parallelize on threads
#pragma omp parallel for reduction(+ : sum)
#endif
for (i = 0; i <= N; i++)
{
s = sigma2(i);
sum += s;
}
return sum % MOD_LIMIT;
}
/** Main function */
int main(int argc, char **argv)
{
uint64_t N = 1000;
if (argc == 2)
{
N = strtoll(argv[1], NULL, 10);
}
else if (argc > 2)
{
fprintf(stderr, "Wrong number of input arguments!\n");
printf("Usage:\t ./sol1.c [N=1000]");
return -1;
}
clock_t start_time = clock();
uint64_t result = sigma(N);
double dtime = clock() - start_time;
printf("N = %" PRIu64 "\nSum: %" PRIu64 "\n", N, result);
printf("Time taken: %.4gms\n", dtime * 1e3 / CLOCKS_PER_SEC);
return 0;
}

View File

@ -1,48 +0,0 @@
/**
* \file
* \brief [Problem 5](https://projecteuler.net/problem=5) solution - Naive
* algorithm (slowest)
*
* \see Faster: problem_5/sol2.c
* \see Fastest: problem_5/sol3.c
*/
#include <stdio.h>
#include <stdlib.h>
/** Pretty naive implementation. Just checks every number if it's devisable by 1
* through 20
* @param n number to check
* @returns 0 if not divisible
* @returns 1 if divisible
*/
static char check_number(unsigned long long n)
{
for (unsigned long long i = 1; i <= 20; ++i)
{
if (n % i != 0)
{
return 0;
}
}
return 1;
}
/**
* @brief Main function
*
* @return 0 on exit
*/
int main(void)
{
for (unsigned long long n = 1;; ++n)
{
if (check_number(n))
{
printf("Result: %llu\n", n);
break;
}
}
return 0;
}

View File

@ -1,59 +0,0 @@
/**
* \file
* \brief [Problem 5](https://projecteuler.net/problem=5) solution - Naive
* algorithm (Improved over problem_5/sol1.c)
* @details Little bit improved version of the naive `problem_5/sol1.c`. Since
* the number has to be divisable by 20, we can start at 20 and go in 20 steps.
* Also we don't have to check against any number, since most of them are
* implied by other divisions (i.e. if a number is divisable by 20, it's also
* divisable by 2, 5, and 10). This all gives a 97% perfomance increase on my
* machine (9.562 vs 0.257)
*
* \see Slower: problem_5/sol1.c
* \see Faster: problem_5/sol3.c
*/
#include <stdio.h>
#include <stdlib.h>
/**
* @brief Hack to store divisors between 1 & 20
*/
static unsigned int divisors[] = {
11, 13, 14, 16, 17, 18, 19, 20,
};
/** Checks if a given number is devisable by every number between 1 and 20
* @param n number to check
* @returns 0 if not divisible
* @returns 1 if divisible
*/
static int check_number(unsigned long long n)
{
for (size_t i = 0; i < 7; ++i)
{
if (n % divisors[i] != 0)
{
return 0;
}
}
return 1;
}
/**
* @brief Main function
*
* @return 0 on exit
*/
int main(void)
{
for (unsigned long long n = 20;; n += 20)
{
if (check_number(n))
{
printf("Result: %llu\n", n);
break;
}
}
return 0;
}

View File

@ -1,60 +0,0 @@
/**
* \file
* \brief [Problem 5](https://projecteuler.net/problem=5) solution (Fastest).
* @details Solution is the LCM of all numbers between 1 and 20.
*
* \see Slowest: problem_5/sol1.c
* \see Slower: problem_5/sol2.c
*/
#include <stdio.h>
/** Compute [Greatest Common Divisor
* (GCD)](https://en.wikipedia.org/wiki/Greatest_common_divisor) of two numbers
* using Euclids algorithm
* @param a first number
* @param b second number
* @return GCD of `a` and `b`
*/
unsigned long gcd(unsigned long a, unsigned long b)
{
unsigned long r;
if (a > b)
{
unsigned long t = a;
a = b;
b = t;
}
while ((r = (a % b)))
{
a = b;
b = r;
}
return b;
}
/** Compute [Least Common Multiple
* (LCM)](https://en.wikipedia.org/wiki/Least_common_multiple) of two numbers
* @param a first number
* @param b second number
* @return LCM of `a` and `b`
*/
unsigned long lcm(unsigned long a, unsigned long b)
{
unsigned long long p = (unsigned long long)a * b;
return p / gcd(a, b);
}
/** Main function
* @returns 0 on exit
*/
int main(void)
{
unsigned long ans = 1;
unsigned long i;
for (i = 1; i <= 20; i++)
{
ans = lcm(ans, i);
}
printf("%lu\n", ans);
return 0;
}

View File

@ -1,19 +0,0 @@
/**
* \file
* \brief [Problem 6](https://projecteuler.net/problem=6) solution
*/
#include <stdio.h>
/** Main function */
int main(void)
{
unsigned s1 = 0, s2 = 0, i;
for (i = 1; i <= 100; i++)
{
s1 += i * i;
s2 += i;
}
unsigned ans = s2 * s2 - s1;
printf("%u\n", ans);
return 0;
}

View File

@ -1,40 +0,0 @@
/**
* \file
* \brief [Problem 7](https://projecteuler.net/problem=7) solution.
* @see Another version: problem_7/sol2.c
*/
#include <stdio.h>
#include <stdlib.h>
/** Main function
* @return 0 on exit
*/
int main(void)
{
char *sieve;
size_t i;
unsigned count = 0;
size_t n = 1000000;
const unsigned target = 10001;
sieve = (char *)calloc(n, sizeof(char));
for (i = 2; i < n; i++)
{
if (!sieve[i])
{
size_t j;
count++;
if (count == target)
{
printf("%lu\n", i);
break;
}
for (j = i * 2; j < n; j += i)
{
sieve[j] = 1;
}
}
}
free(sieve);
return 0;
}

View File

@ -1,38 +0,0 @@
/**
* \file
* \brief [Problem 7](https://projecteuler.net/problem=7) solution.
* @see Faster version problem_7/sol.c
*/
#include <stdio.h>
/** Main function
* @return 0 on exit
*/
int main()
{
int n;
scanf("%d", &n);
int number_of_prime = 0;
for (int i = 2;; i++)
{
int divisors = 0;
for (int j = 1; j <= i; j++)
{
if (i % j == 0)
{
divisors++;
}
}
if (divisors == 2)
{
number_of_prime++;
if (number_of_prime == n)
{
printf("%d", i);
break;
}
}
}
return 0;
}

View File

@ -1,20 +0,0 @@
73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450

View File

@ -1,116 +0,0 @@
/**
* \file
* \brief [Problem 8](https://projecteuler.net/problem=8) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <stdio.h>
#include <stdlib.h>
/** Compute the product of two numbers in a file
*
* \param[in] fp pointer to file that is already open
* \param[in] start_pos line number of the first numer
* \param[in] num_digits number of digits on the line to multiply
* \returns expected product
*/
long long int get_product(FILE *fp, long start_pos, int num_digits)
{
char ch = ' '; /* temporary variable to store character read from file */
unsigned char num = 0; /* temporary variable to store digit read */
long long int prod = 1; /* product accumulator */
int count =
0; /* we use this variable to count number of bytes of file read */
/* accumulate product for num_digits */
for (int i = 0; i < num_digits; i++, count++)
{
/* get character from file */
ch = getc(fp);
/* the ASCII codes of digits is between 0x30 and 0x39.
* any character not in this range implies an invalid character
*/
if (ch < 0x30 || ch > 0x39)
{
if (ch == EOF)
return 0;
i--;
continue;
}
num = ch - 0x30; /* convert character digit to number */
if (num == 0)
{
/* If number is zero, we can skip the next 'num_digits'
* because this '0' will repeat in the next 'num_digit'
* multiplications. Hence, we also do not update the file position
*/
/* NOTE: this is not needed but helps get results faster :) */
return 0;
}
prod *= num; /* accumulate product */
}
/* set file position to the next starting character + 1 */
fseek(fp, -count + 1, SEEK_CUR);
return prod;
}
/** Main function */
int main(int argc, char *argv[])
{
int position = 0;
int num_digits = 4;
long long int prod, max_prod = 0;
/* if second command-line argument is ge=iven,
* use it as the number of digits to compute
* successive product for
*/
if (argc == 2)
num_digits = atoi(argv[1]);
/* open file to read digits from */
FILE *fp = fopen("digits.txt", "rt");
if (!fp)
{
perror("Unable to open file");
return -1;
}
/* loop through all digits in the file */
do
{
/* get product of 'num_digits' from current position in file */
prod = get_product(fp, ftell(fp), num_digits);
if (prod > max_prod)
{
max_prod = prod;
position = ftell(fp) - 1;
}
} while (!feof(fp)); /* loop till end of file is reached */
printf("Maximum product: %lld\t Location: %d^th position\n\t", max_prod,
position);
fseek(fp, position,
SEEK_SET); /* move cursor to identified position in file */
/* loop through all digits */
for (; num_digits > 0; num_digits--)
{
char ch = getc(fp); /* get character */
/* skip invalid character */
if (ch < 0x30 || ch > 0x39)
continue;
if (num_digits > 1)
printf("%c x ", ch);
else
printf("%c = %lld\n", ch, max_prod);
}
fclose(fp); /* close file */
return 0;
}

View File

@ -1,128 +0,0 @@
/**
* \file
* \brief [Problem 8](https://projecteuler.net/problem=8) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* for memmove */
/** Main function */
int main(int argc, char *argv[])
{
int position = 0, num_bad_chars = 0;
int num_digits = 4;
char ch;
unsigned char num, num_prev;
unsigned char *buffer = NULL;
long long int prod = 1, max_prod = 0;
/* if second command-line argument is given,
* use it as the number of digits to compute
* successive product for
*/
if (argc == 2)
num_digits = atoi(argv[1]);
/* allocate memory to store past values */
buffer = calloc(num_digits, sizeof(unsigned char));
if (!buffer)
{
perror("Unable to allocate memory for buffer");
return -1;
}
/* open file to read digits from */
FILE *fp = fopen("digits.txt", "rt");
if (!fp)
{
perror("Unable to open file");
free(buffer); /* free allocated memory */
return -1;
}
/* loop through all digits in the file */
do
{
/* get character from file */
ch = getc(fp);
/* the ASCII codes of digits is between 0x30 and 0x39.
* any character not in this range implies an invalid character
*/
if (ch < 0x30 || ch > 0x39)
{
num_bad_chars++; /* this is used to get the bad characters in the
sequence of 13 characters */
continue;
}
else if (num_bad_chars > 0)
num_bad_chars--;
num = ch - 0x30; /* convert character digit to number */
num_prev = buffer[0]; /* previous n^th digit */
/* left shift the buffer -
* using a for loop or a faster memory move
*/
memmove(buffer, buffer + 1, num_digits - 1);
/*
for (int i = 1; i < num_digits; i++)
buffer[i-1] = buffer[i];
*/
buffer[num_digits - 1] = num; /* save the latest number in buffer */
if (num_prev != 0)
{
/* since product is accumulated, the new product can be obtained by
* simply multiplying the new digit and dividing with the oldest
* digit
*/
prod /= num_prev; /* divide first to avoid over-flows */
prod *= num;
}
else
{
prod = 1;
for (int i = 0; i < num_digits; i++)
{
if (buffer[i] == 0)
{
prod = 0;
break; /* break innermost for-loop */
}
prod *= buffer[i];
}
}
/* check if a new maxima was found */
if (prod > max_prod)
{
max_prod = prod;
position = ftell(fp) - num_bad_chars - num_digits - 1;
}
} while (!feof(fp)); /* loop till end of file is reached */
printf("Maximum product: %lld\t Location: %d^th position\n\t", max_prod,
position);
fseek(fp, position,
SEEK_SET); /* move cursor to identified position in file */
/* loop through all digits */
for (; num_digits > 0; num_digits--)
{
char ch = getc(fp); /* get character */
/* skip invalid character */
if (ch < 0x30 || ch > 0x39)
continue;
if (num_digits > 1)
printf("%c x ", ch);
else
printf("%c = %lld\n", ch, max_prod);
}
fclose(fp); /* close file */
free(buffer); /* free allocated memory */
return 0;
}

View File

@ -1,26 +0,0 @@
/**
* \file
* \brief [Problem 9](https://projecteuler.net/problem=9) solution - A naive
* implementation
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <stdio.h>
/** Main function */
int main(void)
{
for (int a = 1; a < 300; a++)
for (int b = a + 1; b < 400; b++)
for (int c = b + 1; c < 500; c++)
{
if (a * a + b * b == c * c)
if (a + b + c == 1000)
{
printf("%d x %d x %d = %ld\n", a, b, c,
(long int)a * b * c);
return 0;
}
}
return 0;
}

View File

@ -1,43 +0,0 @@
/**
* \file
* \brief [Problem 9](https://projecteuler.net/problem=9) solution
* \author [Krishna Vedala](https://github.com/kvedala)
*
Problem Statement:
A Pythagorean triplet is a set of three natural numbers, \f$a < b < c\f$,
for which, \f$a^2 + b^2 = c^2\f$. For example, \f$3^2 + 4^2 = 9 + 16 = 25 =
5^2\f$. There exists exactly one Pythagorean triplet for which \f$a + b + c =
1000\f$. Find the product abc.
Given \f$a^2 + b^2 = c^2\f$ and \f$a+b+c = n\f$, we can write:
\f{eqnarray*}{
b &=& \frac{n^2 - 2an}{2n - 2a}\\
c &=& n - a - b
\f}
*/
#include <stdio.h>
#include <stdlib.h>
/** Main function */
int main(void)
{
int N = 1000;
for (int a = 1; a < 300; a++)
{
long tmp1 = N * N - 2 * a * N;
long tmp2 = 2 * (N - a);
div_t tmp3 = div(tmp1, tmp2);
int b = tmp3.quot;
int c = N - a - b;
if (a * a + b * b == c * c)
{
printf("%d x %d x %d = %ld\n", a, b, c, (long int)a * b * c);
return 0;
}
}
return 0;
}