2

I'm trying to solver Project Euler #8. It asks to find the largest product of 13 consecutive digits in the following 1000-digit number. Here is my code (in JavaScript):

var bigNumber = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
for(var i = 0, largest = 0; i < 987; i++) {
  for(var j = 0, product = 1; j < 13; j++)
    product *= parseInt(bigNumber.substring(i*13+j, i*13+j+1));
  largest = Math.max(largest, product);
}

The answer is stored in largest. For some reason, largest is NaN, and I do not know why.

I've checked all the data types of all the numbers, especially product and largest, and they always turn up as "number." Their values are never infinity, which may also cause a NaN value.

I was also thinking maybe the products might be too large JavaScript to handle, but I thought it might have thrown a specific error for that.

What is causing this error and how should I solve it?

Community
  • 1
  • 1
Jonathan Lam
  • 16,831
  • 17
  • 68
  • 94
  • Not that this is a bad question but did you try debugging this at all? console.log() maybe? Math with `Infinity` tends to produce `NaN` is more the issue. – djechlin Feb 17 '16 at 23:42
  • @djechlin I did use `console.log()` (quite extensively too). And I didn't know that Infinity returns NaN-- if so, then it is almost definitely the problem. – Jonathan Lam Feb 17 '16 at 23:43
  • 3
    Look, you have i upto 987, and then i * 13, which is 12K+ - far longer than your string. – georg Feb 17 '16 at 23:44
  • OK so please post what largest was right before it became NaN. – djechlin Feb 17 '16 at 23:47
  • @djechlin It was 6270566400, the 13 numbers starting at index 76. – Jonathan Lam Feb 17 '16 at 23:51
  • OK, can you turn it into an [SSCCE](http://sscce.org/) now? – djechlin Feb 17 '16 at 23:51
  • @djechlin What do you mean? It is runnable now, correct? – Jonathan Lam Feb 17 '16 at 23:52
  • It's not the shortest program possible. It sounds like you have the exact loop iteration that is blowing up. You could post just that iteration. Right now you have over a kilobyte of code in your post. – djechlin Feb 17 '16 at 23:53
  • FTR I still don't know how you got NaN from a finite number instead of Infinity. So this is exactly how you debug it (short of using a debugger). – djechlin Feb 17 '16 at 23:54

3 Answers3

5

If you console.log(parseInt(bigNumber.substring(i*13+j, i*13+j+1))); you will see that it will print NaN.

The problem is that your substring is out of bounds.

Ivan
  • 10,052
  • 12
  • 47
  • 78
  • I didn't realize that this was the problem: I hadn't considered that the `i*13` was way out of bounds and should have been just `i`. Oops. – Jonathan Lam Feb 18 '16 at 00:06
  • I see what you were trying to do, but yeah, it was way out of bounds ;) `console.log(i*13+j, bigNumber.length)` would show that too. – Ivan Feb 18 '16 at 00:31
0

I was also thinking maybe the products might be too large JavaScript to handle, but I thought it might have thrown a specific error for that.

Really? It would be very strange to me for a language to support Infinity and throw an error instead of use it.

There's some simple ways to test this for yourself:

for (var i = 0; ; i = i*2) console.log(i); // will eventually print Infinity

(Plus actual documentation.)

djechlin
  • 59,258
  • 35
  • 162
  • 290
0

The NaN problem is due to the way you are calculating which character you need to parseInt on. If you modify the code and keep a watch on largest, you'll see it takes on a value of Infinity, rather than NaN:

var bigNumber = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
var largest = 0;
var product = 1;
for (var i = 0; i < 999; i++) {

  for (var j = 0; j < 13; j++) {

    //Your original code produces NaN error:
    product *= parseInt(bigNumber.substring(i * 13 + j, i * 13 + j + 1));

    // This (more simple code) produces Infinity:
    product *= parseInt(bigNumber.charAt(j));
  }

  largest = Math.max(largest, product);

}
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71