寻找毕达哥拉斯三胞胎

时间:2012-12-07 03:25:05

标签: python algorithm

我需要找到毕达哥拉斯三重奏的所有“a”和“b”值。例如,我会将数字指定为参数,并找到它的所有毕达哥拉斯三元组。以下是我老师给我的一些示例代码:

>>> pytriples(5)
>>> [3,4,5] #would return this
>>> pytriples(25)
>>> [7,24,25] #would return this
>>> [15,20,25] #would return this

基本上,我需要编写pytriples程序,并且因为没有重复“a”和“b”而得到满分。这就是我开发的 - 问题是,我没有办法删除重复项。

这就是我所拥有的:

def pytriples(c):
    newlist = []
    for a in range(0, c):
        if ((c**2 - a**2)**0.5)%1 == 0:
            b = ((c**2 - a**2)**0.5)
            newlist.append([a,b,c])
    for i in newlist: #this part is supposed to remove the duplicates
        print i[0] #was used for debugging but I could not figure out why duplicates were not removed
        if i[0] >= i[1]:
            newlist.remove(i)
    return newlist

6 个答案:

答案 0 :(得分:1)

不确定这是否是你想要的......

你可以从像

这样的三元组元组列表中删除重复项

考虑到你在list l

中获得了所有三元组
In [39]: l
Out[39]: [(1, 2, 3), (2, 3, 4), (2, 1, 3)]

从中删除所有重复项,您可以使用

In [40]: set(map(tuple, [sorted(x) for x in l]))
Out[40]: set([(2, 3, 4), (1, 2, 3)])

然后您可以将其转换为列表以进行进一步处理

In [41]: list(set(map(tuple, [sorted(x) for x in l])))
Out[41]: [(2, 3, 4), (1, 2, 3)]

在你的情况下,

修改你在循环中迭代的列表是个坏主意,

因为只要你删除假设item1,item2就会变成item1但是循环已经迭代了list1中的item1,这样就会跳过检查,你将无法获得所需的输出

考虑一个小例子

In [43]: l
Out[43]: [(1, 2, 3), (2, 3, 4), (2, 1, 3)]

In [44]: for i in l:
   ....:     if i[0] == 2:
   ....:         l.remove(i)
   ....:

In [45]: l
Out[45]: [(1, 2, 3), (2, 1, 3)]

答案 1 :(得分:0)

在迭代时修改列表是to be avoided

通过简单的列表理解,可以按照您想要的方式删除元素:

newlist = [triplet for triplet in newlist if triplet[0] < triplet[1]]

答案 2 :(得分:0)

不要将重复项放入数组中,然后使用传递将它们取回,而不是首先将它们放入数组中。你可以改变

        newlist.append([a,b,c])

        if a<b: newlist.append([a,b,c])

并删除所有for i in newlist:循环及其内容。

(注意,a不能等于b,因为sqrt(2)是不合理的。)

答案 3 :(得分:0)

而不是进行全面扫描,我宁愿预先计算足够的三胞胎并尝试找到匹配。如果所有数字都小于给定的数字,我会在运行中计算更多:)

您的算法有一个正确的想法,但可以更简单地实现。一些基本的三角法可以完全避免重复。

def pytriplets(hypotenuse):
    result = []
    # we only need to check half the triangles,
    # the rest are the same triangles with catheti swapped.
    # 0.71 is approximated sin(pi / 4). Biggest possible catheti are
    # in the isosceles triangle; no bigger should ever be checked. 
    # +1 is because range() excludes the top bound. 
    for a in range(1, int(hypotenuse * 0.71) + 1):
        hypo_squared = hypotenuse * hypotenuse
        a_squared = a * a
        # Square root will give us slight approximation errors;
        # explicitly make our other cathetus integer.
        b = int((hypo_squared  - a_squared) ** 0.5)
        if a_squared + b*b == hypo_squared:
            # A perfect match!
            result.append((hypotenuse, a, b)) # appending a tuple
    return result

print pytriplets(5)
print pytriplets(25)

答案 4 :(得分:0)

我生成了c下方所有完美正方形的列表,并且从列表的两端有两个指针,我将尝试找到哪些数字总和为c ^ 2,直到它们交叉。

def pythogorian_triplets(c):
    c_square = c ** 2
    #list of perfect squares below c_square
    squares = [1]
    #populating the list
    for i in range(1, c - 1):
        squares.append(squares[-1] + (i << 1) + 1)

    i = 0
    j = c - 2
    l = c - 1

    while j >= i and i < l:
        while (squares[i] + squares[j] < c_square) and i < l and j > i:
            i = i + 1
        if squares[i] + squares[j] == c_square:
            print (i + 1, j + 1, c)
        j = j - 1

if __name__ == '__main__':
    pythogorian_triplets(int(raw_input()))

答案 5 :(得分:0)

导入数学

def main():     对于范围内的x(1,1000):         对于范围内的y(1,1000):             对于范围内的z(1,1000):                 如果x * x == y * y + z * z且x + y + z == 1000:                     打印y,z,x                     打印' - '* 50

如果名称 =='主要':     main()