Click here to Skip to main content
15,892,059 members
Please Sign up or sign in to vote.
1.50/5 (2 votes)
See more:
Hi, I was working on solving the 13th problem of project euler. the problem is "Work out the first ten digits of the sum of the following one-hundred 50-digit numbers.", I copied the number into a text file and read each digit then add it to an element in an array and I have solved it, But to read only the first ten digits, I had to skip the next 40 digits by reading them without adding.
C++
for (i = 0; i < 100; i++)
{
        for (j = 0; j < 50; j++)
        {
            if (file >> digit)
            {
                if (j > 9)
                    continue;
                numbers[i] *= 10;
                numbers[i] += (digit - '0');
            }
}
But, of course, doing such thing with a big file will be a big problem so any suggestions for a better solution such as going to the next line or something else ?


Thanks, Samuel.
Posted
Comments
[no name] 3-Jul-15 20:23pm    
I guess I don't understand what your question is. Why don't you read a line, substring the first 10 characters which are the digits you are looking for and use that? You don't need these for loops at all.
PIEBALDconsult 5-Jul-15 15:02pm    
The "lean and mean" technique is to hold only one character from the file at a time -- holding a string is a waste.
PIEBALDconsult 3-Jul-15 20:30pm    
printf ( "0000000000" )
done.
[no name] 3-Jul-15 21:02pm    
I looked at the actual question. For C++ you need to find yourself a Big Integer class to use, read the file, for each line convert the text to your big integer then substring the first 10 digits from the total. All of that should be fewer lines than you posted here.
PIEBALDconsult 3-Jul-15 22:40pm    
I wouldn't bother with a big integer class.

1 solution

Use fseek() to for random access to each line, but consider that it works well only when opening the file as binary (remove text \n translation).
In binary your file layout is as follows:
37107287533902102798797998220837590246510135740250\r\n
46376937677490009712648124896970078050417018260538\r\n
74324986199524741059474233309513058123726617309629\r\n
91942213363574161572522430563301811072406154908250\r\n
23067588207539346171171980310421047513778063246676\r\n
....
53503534226472524250874054075591789781264330331690\r\n

Means that each number starts at
C++
(n-1)*52

Where n is the line number the last two bytes are \r & \n.
If d is the digit you want read on line n then:
digit is at ((n-1)*52)+(50-1-d)

This sample shows as to access file:
C++
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
	FILE *fp;

	fp = fopen("BigNums.txt", "rb");

	if (!fp)
	{
		printf("File not found!\n");
		return -1;
	}

	for(;;)
	{
		char str[128];
		char line[52];

		printf("Insert number line [1-10]: ");
		scanf ("%s", str);
		int n = atoi(str);
		if (n < 0)
			break;
		if (n<1 || n>100)
			continue;

		printf("Insert digit [1-50]: ");
		scanf ("%s", str);
		int digit = atoi(str);
		if (digit<1 || digit>50)
			continue;

		fseek(fp, (n-1)*52, SEEK_SET);
		fread(line, sizeof(line), 1, fp);

		printf("Line [%50.50s] digit [%c], first 10 chars [%10.10s]\n", line, line[49-(digit-1)], line);

	}

	return 0;
}

I choosed to read a whole number each time and access single digits in memory using fread() because fseek() is an heavy function and is not a good idea to use it very often.

If you want read full lines sequentially you can use fgets(). Using it you cannot move back.

P.S. The sample miss checks on file and data format assuming that the file has the specified format and number of entries.
 
Share this answer
 
v7

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900