mirror of
https://github.moeyy.xyz/https://github.com/TheAlgorithms/C.git
synced 2023-10-11 15:56:24 +08:00
Project Euler - Problems 8-16
# Project Euler solutions ## [Problem 08](https://projecteuler.net/problem=8) * `sol1.c1` uses brute-force method, reads the digits `num_digits` times. It requires `num_digits^2` multiplication operations. * `sol2.c` is optimized and requires only one read and `num_digits` multiplications and `num_digits` divisions. ## [Problem 09](https://projecteuler.net/problem=9) Two solution - `sol1.c` uses brute force search and `sol2.c` simplifies the search by creating relations of two unknowns `b` and `c` in terms of the search parameter `a`. ## [Problem 10](https://projecteuler.net/problem=10) * update `.gitignore` to ignore build outputs (*.exe files on windows OS) and visual studio code config folder. * `sol1.c` uses brute force sequential method to search for primes and requires multiple loops. * `sol2.c` uses Sieve of Eratosthenes to simplify the search for primes. ## [Problem 12](https://projecteuler.net/problem=12) * compute triangle numbers on the fly and uses a half-loop search for divisors. ## [Problem 13](https://projecteuler.net/problem=13) * implemented using numbers of arbitrary length, limited only by memory constrains and time. ## [Problem 14](https://projecteuler.net/problem=14) * optimized solution with an option to compile using OpenMP for parallelization ## [Problem 15](https://projecteuler.net/problem=15) * compute triangle numbers on the fly and uses a half-loop search for divisors. ## [Problem 16](https://projecteuler.net/problem=16) * computes any power of 2 and the sum of its digits.
This commit is contained in:
commit
b20488c091
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
||||
*.swp
|
||||
*.exe
|
||||
*.out
|
||||
.vscode/
|
||||
|
19
DIRECTORY.md
19
DIRECTORY.md
@ -224,6 +224,25 @@
|
||||
* [Sol](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2006/sol.c)
|
||||
* Problem 07
|
||||
* [Sol](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2007/sol.c)
|
||||
* Problem 08
|
||||
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2008/sol1.c)
|
||||
* [Sol2](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2008/sol2.c)
|
||||
* Problem 09
|
||||
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2009/sol1.c)
|
||||
* [Sol2](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2009/sol2.c)
|
||||
* Problem 10
|
||||
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2010/sol1.c)
|
||||
* [Sol2](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2010/sol2.c)
|
||||
* Problem 12
|
||||
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2012/sol1.c)
|
||||
* Problem 13
|
||||
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2013/sol1.c)
|
||||
* Problem 14
|
||||
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2014/sol1.c)
|
||||
* Problem 15
|
||||
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2015/sol1.c)
|
||||
* Problem 16
|
||||
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2016/sol1.c)
|
||||
|
||||
## Searching
|
||||
* [Binary Search](https://github.com/TheAlgorithms/C/blob/master/searching/Binary_Search.c)
|
||||
|
20
project_euler/Problem 08/digits.txt
Normal file
20
project_euler/Problem 08/digits.txt
Normal file
@ -0,0 +1,20 @@
|
||||
73167176531330624919225119674426574742355349194934
|
||||
96983520312774506326239578318016984801869478851843
|
||||
85861560789112949495459501737958331952853208805511
|
||||
12540698747158523863050715693290963295227443043557
|
||||
66896648950445244523161731856403098711121722383113
|
||||
62229893423380308135336276614282806444486645238749
|
||||
30358907296290491560440772390713810515859307960866
|
||||
70172427121883998797908792274921901699720888093776
|
||||
65727333001053367881220235421809751254540594752243
|
||||
52584907711670556013604839586446706324415722155397
|
||||
53697817977846174064955149290862569321978468622482
|
||||
83972241375657056057490261407972968652414535100474
|
||||
82166370484403199890008895243450658541227588666881
|
||||
16427171479924442928230863465674813919123162824586
|
||||
17866458359124566529476545682848912883142607690042
|
||||
24219022671055626321111109370544217506941658960408
|
||||
07198403850962455444362981230987879927244284909188
|
||||
84580156166097919133875499200524063689912560717606
|
||||
05886116467109405077541002256983155200055935729725
|
||||
71636269561882670428252483600823257530420752963450
|
100
project_euler/Problem 08/sol1.c
Normal file
100
project_euler/Problem 08/sol1.c
Normal file
@ -0,0 +1,100 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int64_t get_product(FILE *fp, long start_pos, int num_digits)
|
||||
{
|
||||
char ch = ' '; /* temporary variable to store character read from file */
|
||||
uint8_t num = 0; /* temporary variable to store digit read */
|
||||
int64_t 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;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int position = 0;
|
||||
int num_digits = 4;
|
||||
int64_t 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;
|
||||
}
|
117
project_euler/Problem 08/sol2.c
Normal file
117
project_euler/Problem 08/sol2.c
Normal file
@ -0,0 +1,117 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h> /* for memmove */
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int position = 0, num_bad_chars = 0;
|
||||
int num_digits = 4;
|
||||
char ch;
|
||||
uint8_t num, num_prev;
|
||||
uint8_t *buffer = NULL;
|
||||
int64_t 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(uint8_t));
|
||||
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;
|
||||
}
|
18
project_euler/Problem 09/sol1.c
Normal file
18
project_euler/Problem 09/sol1.c
Normal file
@ -0,0 +1,18 @@
|
||||
#include <stdio.h>
|
||||
|
||||
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;
|
||||
}
|
38
project_euler/Problem 09/sol2.c
Normal file
38
project_euler/Problem 09/sol2.c
Normal file
@ -0,0 +1,38 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
Problem Statement:
|
||||
A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,
|
||||
a^2 + b^2 = c^2
|
||||
For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2.
|
||||
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
|
||||
Find the product abc.
|
||||
|
||||
|
||||
Given a^2 + b^2 = c^2 and a+b+c = n, we can write:
|
||||
b = (n^2 - 2*a*n) / (2*n - 2*a)
|
||||
c = n - a - b
|
||||
**/
|
||||
|
||||
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;
|
||||
}
|
37
project_euler/Problem 10/sol1.c
Normal file
37
project_euler/Problem 10/sol1.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char is_prime(long n)
|
||||
{
|
||||
for (long i = 2; i < sqrtl(n) + 1; i++)
|
||||
if ( n % i == 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
long long sum_of_primes(long N)
|
||||
{
|
||||
long long sum = 2;
|
||||
|
||||
for (long i = 3; i < N; i+=2) /* skip even numbers */
|
||||
if (is_prime(i))
|
||||
sum += i;
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
long n = 100;
|
||||
|
||||
if (argc == 2) /* if command line argument is provided */
|
||||
n = atol(argv[1]); /* use that as the upper limit */
|
||||
|
||||
printf("%ld: %lld\n", n, sum_of_primes(n));
|
||||
|
||||
return 0;
|
||||
}
|
51
project_euler/Problem 10/sol2.c
Normal file
51
project_euler/Problem 10/sol2.c
Normal file
@ -0,0 +1,51 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
46
project_euler/Problem 12/sol1.c
Normal file
46
project_euler/Problem 12/sol1.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
long count_divisors(long long n)
|
||||
/*
|
||||
If x = a * b, then both a and b are divisors of x.
|
||||
Since multiplication is commutative, we only need to search
|
||||
till a maximum of a=b = a^2 i.e., till sqrt(x).
|
||||
At every integer till then, there are eaxctly 2 divisors
|
||||
and at a=b, there is only one divisor.
|
||||
*/
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
100
project_euler/Problem 13/num.txt
Normal file
100
project_euler/Problem 13/num.txt
Normal file
@ -0,0 +1,100 @@
|
||||
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
|
136
project_euler/Problem 13/sol1.c
Normal file
136
project_euler/Problem 13/sol1.c
Normal file
@ -0,0 +1,136 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Function to read the number from a file and store it in array.
|
||||
index 0 of output buffer => units place
|
||||
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 arbitraty 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];
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const char N = 50, N2 = N+10; /* length of numbers */
|
||||
char txt_buffer[N+5]; /* temporary buffer */
|
||||
uint8_t number[N]; /* array to store digits of a large number */
|
||||
uint8_t sum[N2]; /* array to store the sum of the large numbers. For
|
||||
safety, we make it twice the length of a number. */
|
||||
|
||||
memset(sum, 0, sizeof(sum)); /* initialize sum array with 0 */
|
||||
|
||||
FILE *fp = fopen("num.txt", "rt"); /* open text file to read */
|
||||
if(!fp)
|
||||
{
|
||||
perror("Unable to open file 'num.txt'.");
|
||||
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 */
|
||||
return 0;
|
||||
}
|
74
project_euler/Problem 14/sol1.c
Normal file
74
project_euler/Problem 14/sol1.c
Normal file
@ -0,0 +1,74 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _OPENMP
|
||||
#include <omp.h>
|
||||
#pragma message ("Using OpenMP parallelization")
|
||||
#else
|
||||
#pragma message ("Not using OpenMP parallelization")
|
||||
#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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* Automatically detects for OPENMP using the _OPENMP macro.
|
||||
**/
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for shared(max_len, max_len_num) schedule(guided)
|
||||
#endif
|
||||
for (long long 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;
|
||||
}
|
35
project_euler/Problem 15/sol1.c
Normal file
35
project_euler/Problem 15/sol1.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
55
project_euler/Problem 16/sol1.c
Normal file
55
project_euler/Problem 16/sol1.c
Normal file
@ -0,0 +1,55 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user