mirror of
https://github.com/TheAlgorithms/C
synced 2024-12-25 04:26:53 +03:00
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:
parent
fb778074c7
commit
454bc8b771
@ -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)
|
||||
|
||||
|
@ -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} )
|
@ -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?
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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.
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
73167176531330624919225119674426574742355349194934
|
||||
96983520312774506326239578318016984801869478851843
|
||||
85861560789112949495459501737958331952853208805511
|
||||
12540698747158523863050715693290963295227443043557
|
||||
66896648950445244523161731856403098711121722383113
|
||||
62229893423380308135336276614282806444486645238749
|
||||
30358907296290491560440772390713810515859307960866
|
||||
70172427121883998797908792274921901699720888093776
|
||||
65727333001053367881220235421809751254540594752243
|
||||
52584907711670556013604839586446706324415722155397
|
||||
53697817977846174064955149290862569321978468622482
|
||||
83972241375657056057490261407972968652414535100474
|
||||
82166370484403199890008895243450658541227588666881
|
||||
16427171479924442928230863465674813919123162824586
|
||||
17866458359124566529476545682848912883142607690042
|
||||
24219022671055626321111109370544217506941658960408
|
||||
07198403850962455444362981230987879927244284909188
|
||||
84580156166097919133875499200524063689912560717606
|
||||
05886116467109405077541002256983155200055935729725
|
||||
71636269561882670428252483600823257530420752963450
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user