Problem 9

Special Pythagorean triplet

A Pythagorean triplet is a set of three natural numbers, , for which,

For example, .
There exists exactly one Pythagorean triplet for which .
Find the product .

https://projecteuler.net/problem=9

Brute Force

function euler9() {
  var a, a2, b, b2, c, c2;
  c = 3;
  while (true) {
    c2 = c*c;
    for (b = 2; b < c; b++) {
      b2 = b*b;
      for (a = 1; a < b; a++) {
        a2 = a*a;
        if (a2 + b2 === c2 && a + b + c === 1000) {
          return a*b*c;
        }
      }
    }
    c++;
  }
}
timer(euler9);
// euler9 x 1: 24.132ms
// 31875000

Starting Point

Because we are looking for , and we can determine a starting point for . If then the max value for and , which is less than .

function euler9() {
  var a, a2, b, b2, c, c2;
  c = 335;
  while (true) {
    c2 = c*c;
    for (b = 2; b < c; b++) {
      b2 = b*b;
      for (a = 1; a < b; a++) {
        a2 = a*a;
        if (a2 + b2 === c2 && a + b + c === 1000) {
          return a*b*c;
        }
      }
    }
    c++;
  }
}
timer(euler9);
// euler9 x 1: 13.301ms
// 31875000

# Time O(n^3)

Using the Requirements

We are still checking a bunch of numbers that can’t be an answer.

, so , and . That means we only need to check one value of per value of . We still need to check every value of less than , that is until , further reducing the values we have to check.

function euler9() {
  var a, a2, b, b2, c, c2;
  c = 335;
  while (true) {
    c2 = c*c;
    b = c - 1;
    a = 1000 - c - b;
    while (a < b) {
      a2 = a*a,
      b2 = b*b;
      if (a2 + b2 === c2) {
        return a*b*c;
      }
      a++;
      b--;
    }
    c++;
  }
}
timer(euler9);
// euler9 x 1: 0.029ms
// 31875000

# Time O(n^2)

Euclid’s formula

For a pythagorean triplet,
$$a = m^2 - n^2 ,\ \, b = 2mn ,\ \, c = m^2 + n^2\; \text{where}\; m > n$$ and because our problem requires $a+b+c=1000$, $$\begin{align*} m^2 -n^2 + 2mn + m^2 + n^2 & = 1000 \\ 2m^2 + 2mn & = 1000 \\ 2m(m+n) & = 1000 \\ m(m+n) & = 500 \\ n & = (500 \div m) - m \end{align*}$$

function euler9() {
  var m, n;
  m = 2;
  while (true) {
    if (500 % m === 0 && 500 / m - m < m) break;
    m++;
  }
  n = 500 / m - m;
  return (m * m - n * n) * (2 * m * n) * (m * m + n * n);
}
timer(euler9);
// euler9 x 1: 0.006ms
// 31875000