Javascript中的毕达哥拉斯三元组公式 - Project Euler Prob 9

时间:2013-04-22 09:21:04

标签: javascript loops formula

我正在尝试解决Project Euler Problem 9

  毕达哥拉斯三元组是一组三个自然数,a< b< C,   为此,a2 + b2 = c2

     

例如,32 + 42 = 9 + 16 = 25 = 52。

     

恰好存在一个毕达哥拉斯三重态,其中a + b + c =   1000.找到产品abc。

我查看了Wikipedia找到毕达哥拉斯三元组的公式并尝试将其翻译成代码。问题是代码输出了错误的答案,但我认为代码是正确的。

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);

5 个答案:

答案 0 :(得分:7)

这是一个解决方案

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);

结果为375 200 425

on jsfiddle

毕达哥拉斯
a 2 + b 2 = c 2

我们也有 a + b + c = 1000

代数,重新排列c到左边 c = 1000 - (a + b)

将c插回毕达哥拉斯
a 2 + b 2 =(1000 - (a + b)) 2

乘出来 a 2 + b 2 = 1000000 - 2000 *(a + b)+(a + b) 2

乘出来 a 2 + b 2 = 1000000 - 2000 *(a + b)+ a 2 + 2 * a * b + b 2

重新排列 2 + b 2 以简化 0 = 1000000 - 2000 *(a + b)+ 2 * a * b

将未知数重新排列到左侧 2000 *(a + b) - 2 * a * b = 1000000

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

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

重新
a(1000 - b)= 500000 - 1000 * b

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

现在输入b,计算a并测试a是Pythagorean Triples

所需的整数

答案 1 :(得分:3)

TGarr,这是对Xotic750答案的解释。

  

我真的不明白你是如何创建算法的。为什么a =到(500000 - 1000 * b)/(1000 - b)......

他以^ 2 + b ^ 2 = c ^ 2和a + b + c = 1000开始,并将它们合并,因为projecteuler上的问题表明只有一组数字,这两个数据都将是真的。这是他如何结合他们。他解决了c的第二个等式,即c = 1000 - (a + b)。然后他将其插入第一个等式,使其变为^ 2 + b ^ 2 =(1000 - (a + b))^ 2。他继续说,直到他能够解决整个等式。一旦他能够做到这一点,他就能够制作一个增加b的单for循环,这比许多其他选项更简单,更优雅。

  

为什么if语句的条件设置为Math.floor(a)=== a?

这只是意味着“a,向下舍入到最接近的整数,与a相同?”换句话说,a是一个整数吗? (复制他的代码,并在console.log ( a );语句之上添加if。这可能有助于你理解那段代码)因为他能够解决a的等式,所以他所要做的只是插入b的数字不同,一旦结果为整数,他就会得到答案。或者至少他知道ab c = 1000 - a - b;告诉他什么是c,这就是她写的所有内容。

答案 2 :(得分:2)

你无法计算那样的权力。

使用Math.pow(a,2)计算^ 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);

答案 3 :(得分:2)

eq 1: 2 + b 2 = c 2

eq 2:a + b + c = 1000

从方程1和方程2我们可以

eq 3:c = 1000 - a - b

将等式3中的c的值替换为等式1,我们得到:

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

等式4的R.H.S是三项式的平方。我们知道这种三项式的正方形是

(a - b - c) 2 = a 2 + b 2 + c 2 - 2ab + 2bc - 2ca

我们得到:

a 2 + b 2 = 1000 2 + a 2 + b 2 - 2 * 1000 * a + 2 * a * b - 2 * b * 1000

现在我们简化以获得L.H.S

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

现在我可以使用它来找出它是一个整数的值,然后使用Math.sqrt(一个 a + b b)来计算c的值。然后我可以检查+ b + c == 1000是否为真。

我的解决方案:

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");
    }
}

输出:

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

Time: 3714 ns

答案 4 :(得分:1)

这是另一种代码较少的解决方案:

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);
    }
  }
}

结果是:31875000:)