最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

loops - Pythagorean Triples Formula in Javascript - Project Euler Prob 9 - Stack Overflow

programmeradmin1浏览0评论

I'm trying to solve the Project Euler Problem 9 :

A Pythagorean triplet is a set of three natural numbers, a < b < c, for which, a2 + b2 = c2

For example, 32 + 42 = 9 + 16 = 25 = 52.

There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the product abc.

I looked on Wikipedia for the formula to find Pythagorean triples and tried to translate it into code. The problem is that the code is outputting the wrong answer, but I think that the code is correct.

var a, b, c;
var pos1, pos2, pos3;
var ans1, ans2, ans3;

for(var n=2; n<=20000; n++) {
  a = 2 * n + 1;
  b = 2 * n * (n +1);
  c = 2 * n * (n +1) + 1;
  if(a<b<c) {
  if(a^2 + b^2 === c^2) {
      pos1 = a;
      pos2 = b;
      pos3 = c;
  }
  if(a + b + c ===1000) {
      ans1 = a;
      ans2 = b;
      ans3 = c;
  }
}
}
console.log(ans1 + " " + ans2 + " " + ans3);

I'm trying to solve the Project Euler Problem 9 :

A Pythagorean triplet is a set of three natural numbers, a < b < c, for which, a2 + b2 = c2

For example, 32 + 42 = 9 + 16 = 25 = 52.

There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the product abc.

I looked on Wikipedia for the formula to find Pythagorean triples and tried to translate it into code. The problem is that the code is outputting the wrong answer, but I think that the code is correct.

var a, b, c;
var pos1, pos2, pos3;
var ans1, ans2, ans3;

for(var n=2; n<=20000; n++) {
  a = 2 * n + 1;
  b = 2 * n * (n +1);
  c = 2 * n * (n +1) + 1;
  if(a<b<c) {
  if(a^2 + b^2 === c^2) {
      pos1 = a;
      pos2 = b;
      pos3 = c;
  }
  if(a + b + c ===1000) {
      ans1 = a;
      ans2 = b;
      ans3 = c;
  }
}
}
console.log(ans1 + " " + ans2 + " " + ans3);
Share Improve this question edited Jan 22, 2015 at 17:15 user2555451 asked Apr 22, 2013 at 9:21 TGarrTGarr 471 gold badge3 silver badges7 bronze badges 2
  • a + b + c = 1000 == for (int a=0;a < 1000;a++) {for (int b=0;b<1000;b++) { for (int c=0;c<1000;c++) { if a + b + c == 1000) { return a + "," + b + "," + c;}}}} – Jeremy Thompson Commented Apr 22, 2013 at 23:04
  • 1 Your previous edit changing a^2 + b^2 === c^2 to Math.pow(a,2) + Math.pow(b,2) === Math.pow(c,2) invalidates the answers. If you "fix" the code in the question it makes the question less relevant because nobody can see the problem. Please correct the code by posting the corrected code as an answer, or by placing the corrected code after a note saying "Edit:" See:Editing questions to fix incorrect code – Justin Commented Apr 23, 2013 at 21:01
Add a comment  | 

5 Answers 5

Reset to default 9

This is a solution

var a;
var c;

for (var b = 1; b < 1000; b += 1) {
    a = (500000 - 1000 * b) / (1000 - b);

    if (Math.floor(a) === a) {
        c = 1000 - a - b;

        break;
    }
}

console.log(a, b, c);

Result is 375 200 425

on jsfiddle

Pythagoras
a2 + b2 = c2

Also we have
a + b + c = 1000

algebra, rearrange c to left
c = 1000 - (a + b)

insert c back in pythagoras
a2 + b2 = (1000 - (a + b))2

multiply out
a2 + b2 = 1000000 - 2000 * (a + b) + (a + b)2

multiply out
a2 + b2 = 1000000 - 2000 * (a + b) + a2 + 2 * a * b + b2

rearrange a2 + b2 to simplify
0 = 1000000 - 2000 * (a + b) + 2 * a * b

rearrange unknowns to left
2000 * (a + b) - 2 * a * b = 1000000

simplify, / 2
1000 * (a + b) - a * b = 500000

factorsize
a(1000 - b) + 1000 * b = 500000

rearrange
a(1000 - b) = 500000 - 1000 * b

a = (500000 - 1000 * b) / (1000 - b)

now input b, calculate a and test if a is an integer as required by Pythagorean Triples

TGarr, here is an explanation to Xotic750's answer.

I don't really understand how you created the algorithm. Why is a = to (500000 - 1000 * b) / (1000 - b) ...

He started with a^2 + b^2 = c^2, and a + b + c = 1000, and combined them because the problem on projecteuler states that there is only 1 set of numbers where both of these statments will be true. Here's how he combined them. He solved the second equation for c to be c = 1000 - (a + b). Then he plugged that into the first equation so that it became a^2 + b^2 = (1000 - (a + b))^2. He continued until he was able to solve the entire equation for a. Once he was able to do that, he was able to make a single for loop that increases b, which is much simpler and more elegant than many other options.

why is the if statement's conditions set to Math.floor(a) === a?

This just means "is a, rounded down to its nearest integer, the same as a?" In other words, is a an integer? (copy his code, and add console.log ( a ); above the if statement. That might help you understand that bit of code) Since he was able to solve the equation for a, all he had to do was plug in different numbers for b, and as soon as the outcome was an integer, he'd have the answer. Or at least he'd know what a and b c = 1000 - a - b; tells him what c is, and that's all she wrote.

Here is another solution with less code:

for(var a = 1; a < 500; a++){
  for(var b = a; b < 1000; b++){
    var c = Math.sqrt(a * a + b * b);
    if(c > b && Number.isInteger(c) && a + b + c == 1000){
      console.log(a * b * c);
    }
  }
}

The result is: 31875000 :)

You can't calculate powers like that.

Use Math.pow(a,2) to calculate a^2

var a, b, c;
var pos1, pos2, pos3;
var ans1, ans2, ans3;

for(var n=2; n<=20000; n++) {
  a = 2 * n + 1;
  b = 2 * n * (n +1);
  c = 2 * n * (n +1) + 1;
  if(a<b<c) {
  if(Math.pow(a,2) + Math.pow(b,2) === Math.pow(c,2)) {
      pos1 = a;
      pos2 = b;
      pos3 = c;
  }
  if(a + b + c ===1000) {
      ans1 = a;
      ans2 = b;
      ans3 = c;
  }
}
}
console.log(ans1 + " " + ans2 + " " + ans3);

eq 1 : a2 + b2 = c2

eq 2 : a + b + c = 1000

From eq 1 and eq 2 we can have

eq 3 : c = 1000 - a - b

Substitute the value of c from eq 3 into eq 1 we get :

eq 4 : a2 + b2 = (1000 - a - b)2

R.H.S of eq 4 is a trinomial squared. We know that square of a trinomial of such kind is

(a - b - c)2 = a2 + b2 + c2 – 2ab + 2bc – 2ca

We get :

a2 + b2 = 10002 + a2 + b2 – 2*1000*a + 2*a*b – 2*b*1000

Now we simplify to get a to the L.H.S

a = (10002 - 2*1000*b)/(2*1000*b)

Now I can use this to find out value of a where it is an integer and then use Math.sqrt( aa + bb ) to calculate the value of c. Then I can check if a+b+c==1000 holds to be true.

My solution:

public class ProjectEuler9 {
    public static void main(String[] args) {
        long start = System.nanoTime();
        double a;
        for(int b=1; b<1000; b++){
            a = ( (Math.pow(1000, 2) - 2000*b ) / (2000- 2*b) );
            if(Math.floor(a) == a) {
                // a is an integer
                double c = Math.sqrt((a*a + b*b));
                System.out.println("a : " + a + " b :" + b + " c : " + c);
                long product = (long) (a*b*c);
                System.out.println("product abc : " + product);
                break;
            } else {
               //a is not an integer.
            }
        }
        long stop = System.nanoTime();
        System.out.println("\nTime: " + (stop - start) / 1000 + " ns");
    }
}

Output :

a : 375.0 b :200 c : 425.0
product abc : 31875000

Time: 3714 ns
发布评论

评论列表(0)

  1. 暂无评论