Generating unique, ordered Pythagorean triplets

前端 未结 19 1260
借酒劲吻你
借酒劲吻你 2020-11-29 16:57

This is a program I wrote to calculate Pythagorean triplets. When I run the program it prints each set of triplets twice because of the if statement. Is there any way I can

19条回答
  •  自闭症患者
    2020-11-29 17:53

    Algorithms can be tuned for speed, memory usage, simplicity, and other things.

    Here is a pythagore_triplets algorithm tuned for speed, at the cost of memory usage and simplicity. If all you want is speed, this could be the way to go.

    Calculation of list(pythagore_triplets(10000)) takes 40 seconds on my computer, versus 63 seconds for ΤΖΩΤΖΙΟΥ's algorithm, and possibly days of calculation for Tafkas's algorithm (and all other algorithms which use 3 embedded loops instead of just 2).

    def pythagore_triplets(n=1000):
       maxn=int(n*(2**0.5))+1 # max int whose square may be the sum of two squares
       squares=[x*x for x in xrange(maxn+1)] # calculate all the squares once
       reverse_squares=dict([(squares[i],i) for i in xrange(maxn+1)]) # x*x=>x
       for x in xrange(1,n):
         x2 = squares[x]
         for y in xrange(x,n+1):
           y2 = squares[y]
           z = reverse_squares.get(x2+y2)
           if z != None:
             yield x,y,z
    
    >>> print list(pythagore_triplets(20))
    [(3, 4, 5), (5, 12, 13), (6, 8, 10), (8, 15, 17), (9, 12, 15), (12, 16, 20)]
    

    Note that if you are going to calculate the first billion triplets, then this algorithm will crash before it even starts, because of an out of memory error. So ΤΖΩΤΖΙΟΥ's algorithm is probably a safer choice for high values of n.

    BTW, here is Tafkas's algorithm, translated into python for the purpose of my performance tests. Its flaw is to require 3 loops instead of 2.

    def gcd(a, b):
      while b != 0:
        t = b
        b = a%b
        a = t
      return a
    
    def find_triple(upper_boundary=1000):
      for c in xrange(5,upper_boundary+1):
        for b in xrange(4,c):
          for a in xrange(3,b):
            if (a*a + b*b == c*c and gcd(a,b) == 1):
              yield a,b,c
    

提交回复
热议问题