我该如何修复这个毕达哥拉斯三重态程序?

How can I fix this Pythagorean Triplet program?

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

Pythagorean triplets are sets of 3 positive integers a, b, c satisfying the relationship a2 + b2 = c2. The smallest and best-known Pythagorean triple is (a, b, c) = (3, 4, 5). Write a program that reads a command line argument n and prints to the screen all Pythagorean triplets whose sum is less than n (i.e., a+b+c < n) and that are not multiple of the (3, 4, 5) triplet. Your program will represent triplets as 3-tuples, and should consist of three functions:

  • a function that takes in a tuple and returns a boolean indicating whether the Pythagorean relationship holds or not.
  • a function that takes in a tuple and returns a boolean indicating whether a triplet is a multiple of the smallest triplet or not.
  • a function that takes in an integer n and generates the Pythagorean triplets as specified above. The function should return a list of tuples.

The main portion of your program pythagore.py will read in the command line input, call the last function described above, and print the results one triplet per line.

我的问题是我在不同的地方得到了相同的组合 订单例如:(5,12,13)​​,(13,12,5)...etc

您的主例程缺乏逻辑。没有什么可以强制三元组只有一个顺序:你的 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 仍然存在问题:您的检查在逻辑上不等同于 "smallest triple"。相反,检查这三个数是否互质。由于 Stack Overflow 每次发帖只允许一个问题,而且这个问题很容易在线研究,我将把它留给学生作为练习。 :-)

因为三个数字永远不会相同,所以您可以将第二个和第三个范围从 (1,n) 相应地更改为 (x+1,n) 和 (y+1,n)。

一个简单的解决方案是跟踪已经找到的那些并添加检查以避免重复它们。下面使用 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_)

您可以使用 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 大于 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])