我正在尝试解决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);
答案 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的数字不同,一旦结果为整数,他就会得到答案。或者至少他知道a
和b
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:)