如何修复毕达哥拉斯三重奏程序?

时间:2018-10-25 18:11:00

标签: python python-3.x pythagorean

import sys

def pythTrue(a,b,c):
    (A,B,C) = (a*a,b*b,c*c)
    if A + B == C or B + C == A or A + C == B:
        return True

def smallestTrip(a,b,c):
    if pythTrue(a,b,c) == True:
        if (a+b+c)%12 == 0:
            return True
        else:
            return False

def tuplePyth(n):
    list_=[]
    for x in range(1, n):
        for y in range(1, n):
            for z in range (1, n):
                if x+y+z<=n:
                    if smallestTrip(x, y, z)==False:
                        list_.append([x,y,z])
    print (list_)

tuplePyth(int(sys.argv[1]))
  毕达哥拉斯三胞胎是3个正整数a,b,c的集合   满足关系a 2 + b 2 =   c 2 。最小和最著名的毕达哥拉斯三元组是   (a,b,c)=(3,4,5)。编写一个读取命令行的程序   参数n并将所有求和的毕达哥拉斯三元组输出到屏幕上   小于n(即a + b + c      
      
  • 接受元组的函数   并返回一个布尔值,指示勾股关系是否成立。
  •   
  • 一个接受元组并返回的函数   一个布尔值,指示三元组是否为最小的倍数   三胞胎与否。
  •   
  • 一个接受整数n并生成的函数   如上所述的毕达哥拉斯三胞胎。该功能应   返回元组列表。
  •   
     

程序pythagore.py的主要部分将在命令中读取   行输入,调用上述最后一个函数,然后打印   导致每行1个三联体。

我的问题是我得到的是不同的相同组合 订单例如:(5,12,13),(13,12,5)...等

4 个答案:

答案 0 :(得分:0)

您在主例程中缺少逻辑。没有强制要求三元组仅按一个顺序进行操作:您的xy是可互换的,并且您保证可以同时选中两者。

相反,用循环限制强制x < y,然后确保在yz的值变得太大而无法使用时停止。请注意,这省去了您对三者之和的检查。

def tuplePyth(n):
    list_=[]
    for x in range(1, n):
        for y in range(1, n):
            for z in range (1, n):
                if x+y+z<=n:
                    if smallestTrip(x, y, z)==False:
                        list_.append([x,y,z])
    print (list_)

相反:

def tuplePyth(n):
    list_=[]
    for x in range(1, n):
        for y in range(x + 1, (n - x) // 2):
            for z in range (y + 1, n - x - y):
                if smallestTrip(x, y, z)==False:
                    list_.append([x,y,z])
    print (list_)

n = 100的输出:

[[5, 12, 13], [7, 24, 25], [8, 15, 17], [9, 40, 41], [15, 36, 39], [16, 30, 34], [20, 21, 29]]

请注意,smallestTrip仍然存在问题:您的支票在逻辑上不等同于“最小三重”。相反,请检查三个数字是否是质数。由于Stack Overflow每次发帖只允许一个问题,而且该问题很容易在线研究,因此我将其留给学生练习。 :-)

答案 1 :(得分:0)

一个简单的解决方案是跟踪发现的铅并添加检查以避免重复。以下使用set存储已经生成的元素,并对每个三元组中的元素进行排序,以使它们的顺序无关紧要。

def tuplePyth(n):
    list_=[]
    seen = set()
    for x in range(1, n):
        for y in range(1, n):
            for z in range (1, n):
                if tuple(sorted((x,y,z))) not in seen:
                    if x+y+z <= n:
                        if smallestTrip(x, y, z) == False:
                            list_.append([x,y,z])
                    seen.add((x,y,z))
    print (list_)

答案 2 :(得分:0)

您可以使用itertools:

 import itertools.combinations_with_replacement as cwr
 list_ = [triple for triple in cwr(range(n),3) if sum(triple)<n and not smallestTrip(triple)]

您还可以强制数字与限制顺序一致。此外,您可以通过意识到如果我们将a定义为最小的数字,则它必须小于n / 3(b和c都至少与a一样大),从而简化查找a,b,c的过程。大于n / 3,则a,b和c之和将大于n)。同样,b必须小于n / 2。找到a和b的所有组合后,就可以找到所有大于b且小于n-a-b的c。

list_=[]
for x in range(1, n//3):
    for y in range(x+1, n//2):
        for z in range (x+y+1, n-x-y):
                if not smallestTrip(x, y, z):
                    list_.append([x,y,z])

答案 3 :(得分:-1)

由于这三个数字永远都不相同,因此只需将第二个和第三个范围从(1,n)分别更改为(x + 1,n)和(y + 1,n)。