Reputation: 193
Right now I calculate (primitive) Pythagorean Triples in this way
def generateTriples(limit):
for n in xrange(1, limit):
if (n**2 + (n+1)**2 > limit):
break
for m in xrange(n+1, limit, 2):
if (n**2 + m**2 > limit):
break
if (gcd(n, m) > 1):
continue
yield (m**2 - n**2, 2*m*n, m**2 + n**2)
But what this does is output all triples where all legs fall less than or equal to the limit. For example:
for triple in generateTriples(25):
print triple
'''
(3, 4, 5)
(15, 8, 17)
(5, 12, 13)
(7, 24, 25)
'''
But what I'd like to do is change it around so that I am only limiting the legs. The hypotenuse can be as large as it wants -- I just want the min(leg1, leg2) to be less than or equal to the limit.
I'm also aiming to generate nonprimitives, which means scaling by k on all terms (also such that min(leg1, leg2) is <=the limit, but I worry that I will get duplicates this way.
Any advice would be much appreciated.
Upvotes: 3
Views: 528
Reputation: 176780
This function determines the maximum possible hypoteneuse that could be paired with a leg in a perfect triple, then uses your function to actually search for the triples:
from fractions import gcd
def generateTriples(limit):
for n in xrange(1, limit):
if (n**2 + (n+1)**2 > limit):
break
for m in xrange(n+1, limit, 2):
if (n**2 + m**2 > limit):
break
if (gcd(n, m) > 1):
continue
yield (m**2 - n**2, 2*m*n, m**2 + n**2)
def generate_triples_limit_leg(leg):
limit = leg**2 / 2 + 1
for triple in generateTriples(limit):
if min(triple) <= leg:
yield triple
print list(generate_triples_limit_leg(i))
This version doesn't find all triples, but works directly on the min leg:
def generate_triples(limit):
# for each number up to the limit
# Python ranges don't include the max number
# start from 4 because 1 and 2 are invalid
# and 3 and 4 give the same triplet
for i in range(4, limit + 1):
# if i is odd
if i % 2:
# the two larger legs are the integers
# above and below half of the square of the smallest leg
# // is floor division
big = i**2 // 2
yield i, big, big + 1
else:
# the two other legs are the integers
# above and below half of the smallest leg squared
big = (i // 2)**2
yield i, big - 1, big + 1
print list(generate_triples(10))
# [(3, 4, 5), (5, 12, 13), (6, 8, 10), (7, 24, 25),
# (8, 15, 17), (9, 40, 41), (10, 24, 26)]
Upvotes: 3