如何循环一个数字,以便数字遍历每个可能的值?

时间:2016-04-03 22:45:17

标签: python arrays loops

当我遇到问题时,我在Project Euler中做了问题9。我的计划已经取得了长期的进展。超过半小时。这是我的代码。

def Problem9():
    a = 1
    b = 1
    c = 1
    x = []
    while(a + b + c != 1000):
        a = a + 1
        for i in range(0,1000):
            c = 1000 - (a + b)
            if a < b < c:
                if (a*a) + (b*b) == (c*c):
                    x.append(a*b*c)
                    print(a*b*c)
            b = b + 1
    print(x)

Problem9()

这基本上应该找出所有Pythagorean三元组加起来一千个(链接到问题以便你可以更好地理解它:https://projecteuler.net/problem=9)我的代码中是否有问题我可以修复或我的代码根本错了吗?

5 个答案:

答案 0 :(得分:5)

由于您知道这三个数字必须加起来为1000a < b < c,因此您可以利用这一事实更有效地(并且干净地)循环。

def Problem9():
    for a in range(1000):
        for b in range(a,1000):
            if a**2 + b**2 == (1000 - a - b)**2:
                return a*b*(1000 - a - b)

在这里,您将a从1循环到1,000。因为b必须大于a,所以你从b到lo超过b。然后,既然你知道1000 = a + b + c,那么c = 1000 - a - b,你可以测试毕达哥拉斯条件,而不需要再循环。

答案 1 :(得分:2)

  毕达哥拉斯三元组是一组三个自然数,a&lt; b&lt; c,对于&gt;其中a2 + b2 = c2。   恰好存在一个毕达哥拉斯三重态,其中a + b + c = 1000。

这将有效

def pythagorean_tiplet():
  a = 1
  while(a < 1000):
      b = a + 1 # note this, b is starting from a + 1, since b starting from 0 is useless and will only add to the running time.
      while (b < 1000):
        result = a**2 + b**2
        c = math.sqrt(result) 
        if (( a + b + c) == 1000 and (a < b < c)): #test for conditions
            return a * b * c
        b += 1
      a += 1


print(pythagorean_tiplet())

此 算法绝对不适用于周长s> 1 000 000。 有一种更快的算法可用于解决它。您可以搜索parametrisation of Pythagorean triplets

答案 2 :(得分:2)

你是系统

(*1) a + b + c = 1000
(*2) a² + b² = c²

如果

a + b + c = 1000

然后

a + b = 1000 - c
(a + b)² = (1000 - c)²
a² + 2ab + b² = 1000² - 2000c + c²
( a² + b² ) + 2ab = 1000² - 2000c + c²

但是,通过(* 2),(a²+b²)=c²,然后

c² + 2ab = 1000² - 2000c + c²
2ab = 1000² - 2000c
2000c = 1000² - 2ab

然后

c = 500 - ab/(1000)

所以,现在,你有了新系统:

(*3) a + b + 500 - ab/(1000) = 1000
(*4) c = 500 - ab/(1000)

此外, a b c 是整数,a<b<c; 如果a>332 a 必须至少 333 ,然后, b 应该至少 334 ,然后, c 至少应该是 335 ; 333 + 334 + 335 = 1002

通过更多的数学运算,您可以更轻松地完成这项任务。

def p():
    for a in range(1,333):
        for b in range(a+1,(1000-a)/2):
            if ( 1000*a + 1000*b + 500000 - a*b == 1000000 ):
                c=500-((a*b)/1000)
                print (a,b,c);print a*b*c
                return
p()

结果:

  

时间python Special_Pythagorean_triplet.py

     

(200, 375, 425) 31875000

     

真实 0m0.041s 用户 0m0.036s sys 0m0.000s

if 声明中:

if ( 1000*a + 1000*b + 500000 - a*b == 1000000 )

你可以使用:

if ( a + b + 500 - (a*b)/1000 == 1000 )

但是,在这种情况下,只有整数才有意义: 与第一个一起,你可以解决分裂及其舍入问题。

答案 3 :(得分:1)

更好的方法是使用itertools

https://docs.python.org/3.4/library/itertools.html

from itertools import product
def ff1():
    for r in product(range(1,1000),repeat=3):
        a,b,c=r
        if a+b+c==1000:
            if a<b<c:
                if a**2+b**2==c**2:
                    print(a,b,c)
                    print(a*b*c)

ff1()

答案 4 :(得分:0)

这段代码真的很尴尬。虽然条件本身有点不对,但你会在前3个数字中加上1000,然后退出。另一个错误的事情是B没有重置。您可以像Ibukun建议的那样做,但这不是这种直接方法的最佳方式。你不需要检查它们是否总和1000.它的方式更简单:

  1. 从3到997迭代A
  2. 从A + 1到999-A
  3. 迭代B.
  4. C = 1000 - A - B(你不知道如何检查总和,你已经这样做了)
  5. 检查它们是否是三联体,如果它们已经完成,你就完成了!
  6. 一旦你输入正确的答案,你可以查看其他很棒的方法,它们更有趣