2020-06-05 20:53:38 +03:00
|
|
|
/**
|
|
|
|
* \file
|
|
|
|
* \brief [Problem 13](https://projecteuler.net/problem=13) solution
|
2020-06-06 21:51:49 +03:00
|
|
|
* \author [Krishna Vedala](https://github.com/kvedala)
|
2020-06-05 20:53:38 +03:00
|
|
|
*/
|
2020-03-30 17:48:24 +03:00
|
|
|
#include <stdint.h>
|
2020-05-29 23:23:24 +03:00
|
|
|
#include <stdio.h>
|
2020-03-30 17:48:24 +03:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2020-06-05 20:53:38 +03:00
|
|
|
/** 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
|
2020-03-30 17:48:24 +03:00
|
|
|
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);
|
2020-04-24 03:17:32 +03:00
|
|
|
if (!l)
|
2020-03-30 17:48:24 +03:00
|
|
|
{
|
2020-04-24 03:17:32 +03:00
|
|
|
perror("Error reading line.");
|
2020-03-30 17:48:24 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
// printf("Number: %s\t length: %ld, %ld\n", buffer, strlen(buffer), l);
|
2020-04-24 03:17:32 +03:00
|
|
|
|
2020-03-30 17:48:24 +03:00
|
|
|
long L = strlen(buffer);
|
|
|
|
|
2020-04-24 03:17:32 +03:00
|
|
|
for (int i = 0; i < L; i++)
|
2020-07-13 06:49:09 +03:00
|
|
|
{
|
2020-03-30 17:48:24 +03:00
|
|
|
if (buffer[i] < 0x30 || buffer[i] > 0x39)
|
|
|
|
{
|
|
|
|
perror("found inavlid character in the number!");
|
|
|
|
return -1;
|
2020-04-24 03:17:32 +03:00
|
|
|
}
|
|
|
|
else
|
2020-07-13 06:49:09 +03:00
|
|
|
{
|
2020-04-24 03:17:32 +03:00
|
|
|
out_int[L - i - 1] = buffer[i] - 0x30;
|
2020-07-13 06:49:09 +03:00
|
|
|
}
|
|
|
|
}
|
2020-03-30 17:48:24 +03:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-07-13 06:49:09 +03:00
|
|
|
* Function to add arbitrary length decimal integers stored in an array.
|
2020-03-30 17:48:24 +03:00
|
|
|
* a + b = c = new b
|
2020-06-28 22:18:52 +03:00
|
|
|
*/
|
2020-03-30 17:48:24 +03:00
|
|
|
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);
|
2020-07-13 06:49:09 +03:00
|
|
|
c[i] = carry + a[i] + b[i]; // NOLINT // This is a known false-positive
|
|
|
|
if (c[i] > 9) /* check for carry */
|
2020-03-30 17:48:24 +03:00
|
|
|
{
|
|
|
|
carry = 1;
|
|
|
|
c[i] -= 10;
|
2020-04-24 03:17:32 +03:00
|
|
|
}
|
|
|
|
else
|
2020-07-13 06:49:09 +03:00
|
|
|
{
|
2020-03-30 17:48:24 +03:00
|
|
|
carry = 0;
|
2020-07-13 06:49:09 +03:00
|
|
|
}
|
2020-03-30 17:48:24 +03:00
|
|
|
// printf("= %d, %d\n", carry, c[i]);
|
|
|
|
}
|
|
|
|
|
2020-04-24 03:17:32 +03:00
|
|
|
for (int i = N; i < N + 10; i++)
|
2020-03-30 17:48:24 +03:00
|
|
|
{
|
2020-04-24 03:17:32 +03:00
|
|
|
if (carry == 0)
|
2020-07-13 06:49:09 +03:00
|
|
|
{
|
2020-03-30 17:48:24 +03:00
|
|
|
break;
|
2020-07-13 06:49:09 +03:00
|
|
|
}
|
2020-03-30 17:48:24 +03:00
|
|
|
// printf("\t0 + %d + %d ", b[i], carry);
|
|
|
|
c[i] = carry + c[i];
|
|
|
|
if (c[i] > 9)
|
|
|
|
{
|
|
|
|
carry = 1;
|
|
|
|
c[i] -= 10;
|
2020-04-24 03:17:32 +03:00
|
|
|
}
|
|
|
|
else
|
2020-07-13 06:49:09 +03:00
|
|
|
{
|
2020-03-30 17:48:24 +03:00
|
|
|
carry = 0;
|
2020-07-13 06:49:09 +03:00
|
|
|
}
|
2020-03-30 17:48:24 +03:00
|
|
|
// printf("= %d, %d\n", carry, c[i]);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-06-05 20:53:38 +03:00
|
|
|
/** Function to print a long number */
|
2020-03-30 17:48:24 +03:00
|
|
|
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 */
|
2020-06-28 18:25:37 +03:00
|
|
|
while (number[start_pos] == 0) start_pos--;
|
2020-03-30 17:48:24 +03:00
|
|
|
|
|
|
|
/* if end_pos < 0, print all digits */
|
|
|
|
if (num_digits_to_print < 0)
|
2020-07-13 06:49:09 +03:00
|
|
|
{
|
2020-03-30 17:48:24 +03:00
|
|
|
end_pos = 0;
|
2020-07-13 06:49:09 +03:00
|
|
|
}
|
2020-03-30 17:48:24 +03:00
|
|
|
else if (num_digits_to_print <= start_pos)
|
2020-07-13 06:49:09 +03:00
|
|
|
{
|
2020-03-30 17:48:24 +03:00
|
|
|
end_pos = start_pos - num_digits_to_print + 1;
|
2020-07-13 06:49:09 +03:00
|
|
|
}
|
2020-03-30 17:48:24 +03:00
|
|
|
else
|
|
|
|
{
|
|
|
|
fprintf(stderr, "invalid number of digits argumet!\n");
|
|
|
|
return -1;
|
|
|
|
}
|
2020-04-24 03:17:32 +03:00
|
|
|
|
2020-06-28 18:25:37 +03:00
|
|
|
for (int i = start_pos; i >= end_pos; i--) putchar(number[i] + 0x30);
|
2020-04-24 03:17:32 +03:00
|
|
|
|
2020-03-30 17:48:24 +03:00
|
|
|
putchar('\n');
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-06-05 20:53:38 +03:00
|
|
|
/** Main function */
|
2020-03-30 17:48:24 +03:00
|
|
|
int main(void)
|
|
|
|
{
|
2020-07-13 06:49:09 +03:00
|
|
|
/* number of digits of the large number */
|
|
|
|
const int N = 10;
|
|
|
|
/* number of digits in output number */
|
|
|
|
const int N2 = N + 10;
|
|
|
|
|
2020-04-24 03:17:32 +03:00
|
|
|
// const char N = 50, N2 = N+10; /* length of numbers */
|
2020-07-13 07:12:57 +03:00
|
|
|
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. */
|
2020-03-30 17:48:24 +03:00
|
|
|
|
2020-04-24 03:17:32 +03:00
|
|
|
FILE *fp = fopen("num.txt", "rt"); /* open text file to read */
|
|
|
|
if (!fp)
|
2020-03-30 17:48:24 +03:00
|
|
|
{
|
|
|
|
perror("Unable to open file 'num.txt'.");
|
2020-07-13 07:14:29 +03:00
|
|
|
free(txt_buffer);
|
|
|
|
free(sum);
|
|
|
|
free(number);
|
2020-03-30 17:48:24 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int count = 0;
|
2020-04-24 03:17:32 +03:00
|
|
|
get_number(fp, txt_buffer, sum); /* 0 + = first_number = first_number */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
count++;
|
2020-03-30 17:48:24 +03:00
|
|
|
if (get_number(fp, txt_buffer, number) != 0)
|
2020-07-13 06:49:09 +03:00
|
|
|
{
|
2020-03-30 17:48:24 +03:00
|
|
|
break;
|
2020-07-13 06:49:09 +03:00
|
|
|
}
|
2020-03-30 17:48:24 +03:00
|
|
|
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);
|
|
|
|
|
2020-04-24 03:17:32 +03:00
|
|
|
fclose(fp); /* close file */
|
2020-07-13 07:12:57 +03:00
|
|
|
free(txt_buffer);
|
|
|
|
free(sum);
|
|
|
|
free(number);
|
2020-03-30 17:48:24 +03:00
|
|
|
return 0;
|
2020-06-05 20:53:38 +03:00
|
|
|
}
|