diff --git a/.gitignore b/.gitignore index 53f12f0f..8d3f5c3f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ *.swp +*.exe *.out +.vscode/ diff --git a/DIRECTORY.md b/DIRECTORY.md index 5ef05421..b3907e20 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -223,6 +223,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) diff --git a/project_euler/Problem 08/digits.txt b/project_euler/Problem 08/digits.txt new file mode 100644 index 00000000..dfd91530 --- /dev/null +++ b/project_euler/Problem 08/digits.txt @@ -0,0 +1,20 @@ +73167176531330624919225119674426574742355349194934 +96983520312774506326239578318016984801869478851843 +85861560789112949495459501737958331952853208805511 +12540698747158523863050715693290963295227443043557 +66896648950445244523161731856403098711121722383113 +62229893423380308135336276614282806444486645238749 +30358907296290491560440772390713810515859307960866 +70172427121883998797908792274921901699720888093776 +65727333001053367881220235421809751254540594752243 +52584907711670556013604839586446706324415722155397 +53697817977846174064955149290862569321978468622482 +83972241375657056057490261407972968652414535100474 +82166370484403199890008895243450658541227588666881 +16427171479924442928230863465674813919123162824586 +17866458359124566529476545682848912883142607690042 +24219022671055626321111109370544217506941658960408 +07198403850962455444362981230987879927244284909188 +84580156166097919133875499200524063689912560717606 +05886116467109405077541002256983155200055935729725 +71636269561882670428252483600823257530420752963450 diff --git a/project_euler/Problem 08/sol1.c b/project_euler/Problem 08/sol1.c new file mode 100644 index 00000000..3577e3a0 --- /dev/null +++ b/project_euler/Problem 08/sol1.c @@ -0,0 +1,100 @@ +#include +#include + +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; +} diff --git a/project_euler/Problem 08/sol2.c b/project_euler/Problem 08/sol2.c new file mode 100644 index 00000000..be31b11c --- /dev/null +++ b/project_euler/Problem 08/sol2.c @@ -0,0 +1,117 @@ +#include +#include +#include /* 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; +} diff --git a/project_euler/Problem 09/sol1.c b/project_euler/Problem 09/sol1.c new file mode 100644 index 00000000..1893425c --- /dev/null +++ b/project_euler/Problem 09/sol1.c @@ -0,0 +1,18 @@ +#include + +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; +} \ No newline at end of file diff --git a/project_euler/Problem 09/sol2.c b/project_euler/Problem 09/sol2.c new file mode 100644 index 00000000..fc52c588 --- /dev/null +++ b/project_euler/Problem 09/sol2.c @@ -0,0 +1,38 @@ +#include +#include + +/** + 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; +} \ No newline at end of file diff --git a/project_euler/Problem 10/sol1.c b/project_euler/Problem 10/sol1.c new file mode 100644 index 00000000..a67dc281 --- /dev/null +++ b/project_euler/Problem 10/sol1.c @@ -0,0 +1,37 @@ +#include +#include +#include + +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; +} \ No newline at end of file diff --git a/project_euler/Problem 10/sol2.c b/project_euler/Problem 10/sol2.c new file mode 100644 index 00000000..d746fcd7 --- /dev/null +++ b/project_euler/Problem 10/sol2.c @@ -0,0 +1,51 @@ +#include +#include +#include + + +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; +} \ No newline at end of file diff --git a/project_euler/Problem 12/sol1.c b/project_euler/Problem 12/sol1.c new file mode 100644 index 00000000..01e8438f --- /dev/null +++ b/project_euler/Problem 12/sol1.c @@ -0,0 +1,46 @@ +#include +#include +#include + +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; +} \ No newline at end of file diff --git a/project_euler/Problem 13/num.txt b/project_euler/Problem 13/num.txt new file mode 100644 index 00000000..bb9d196a --- /dev/null +++ b/project_euler/Problem 13/num.txt @@ -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 \ No newline at end of file diff --git a/project_euler/Problem 13/sol1.c b/project_euler/Problem 13/sol1.c new file mode 100644 index 00000000..a7ba1065 --- /dev/null +++ b/project_euler/Problem 13/sol1.c @@ -0,0 +1,136 @@ +#include +#include +#include +#include + +/* 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; +} \ No newline at end of file diff --git a/project_euler/Problem 14/sol1.c b/project_euler/Problem 14/sol1.c new file mode 100644 index 00000000..e8af5ad6 --- /dev/null +++ b/project_euler/Problem 14/sol1.c @@ -0,0 +1,74 @@ +#include +#include + +#ifdef _OPENMP + #include + #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; +} \ No newline at end of file diff --git a/project_euler/Problem 15/sol1.c b/project_euler/Problem 15/sol1.c new file mode 100644 index 00000000..7775a679 --- /dev/null +++ b/project_euler/Problem 15/sol1.c @@ -0,0 +1,35 @@ +#include +#include +#include + + +/** + * 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; +} \ No newline at end of file diff --git a/project_euler/Problem 16/sol1.c b/project_euler/Problem 16/sol1.c new file mode 100644 index 00000000..6c307a40 --- /dev/null +++ b/project_euler/Problem 16/sol1.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +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; +} \ No newline at end of file