## PythagoreanTriples.jl

Pythagorean Triples
Author scheinerman
Popularity
4 Stars
Updated Last
1 Year Ago
Started In
February 2023

# `PythagoreanTriples`

A Pythagorean Triple is a list of three positive integers `(a,b,c)` with the property that `a^2 + b^2 == c^2`. That is, they are integers and the lengths of the two legs and the hypotenuse of a right triangle.

In this module, a `PythagoreanTriple` is a container that holds three such integers with the additional property that `a<b`.

## Construction

### Three-parameter construction

A Pythagorean triple can be constructed simply by specifying the lengths of the legs and hypotenuse of a right triangle

``````julia> using PythagoreanTriples

julia> T = PythagoreanTriple(4,3,5)
PythagoreanTriple(3, 4, 5)
``````

If the three integers are not the side lengths of a right triangle, an error is thrown:

``````julia> T = PythagoreanTriple(4,5,6)
ERROR: (4, 5, 6) does not define a Pythagorean triple
``````

In addition, the three side lengths can be given as a tuple:

``````julia> abc = (4,3,5)
(4, 3, 5)

julia> PythagoreanTriple(abc)
PythagoreanTriple(3, 4, 5)
``````

### Two-parameter construction

Pythagorean triples can be created from a pair of integers `u,v` in which the legs of the right triangle are `abs(u^2 - v^2)` and `abs(2*u*v)`, and the hypotenuse is `u^2 + v^2`.

A user can give the values `u` and `v` to create a Pythagorean triple:

``````julia> T = PythagoreanTriple(2,5)
PythagoreanTriple(20, 21, 29)
``````

Note that the integers `u` and `v` must be distinct and nonzero:

``````julia> PythagoreanTriple(0,5)
ERROR: (0, 5) does not yield a PythagoreanTriple

julia> PythagoreanTriple(2,2)
ERROR: (2, 2) does not yield a PythagoreanTriple
``````

## Generation

We call a Pythagorean triple `(a,b,c)` primitive provided `gcd(a,b) == 1`. Thus `(3,4,5)` is primitive but `(6,8,10)` is not.

Use `TripleGenerator` to create an iterator for primitive Pythagorean triples. The iterator `TripleGenerator(n)` will create `n` primitive triples:

``````julia> for t in TripleGenerator(5)
println(t)
end
PythagoreanTriple(3, 4, 5)
PythagoreanTriple(5, 12, 13)
PythagoreanTriple(8, 15, 17)
PythagoreanTriple(7, 24, 25)
PythagoreanTriple(20, 21, 29)
``````

If `n` is omitted (or negative) the iterator will produce values endlessly. For example:

``````julia> for t in TripleGenerator()
a,b,c = make_tuple(t)
if a > 1000
println(t)
break
end
end
PythagoreanTriple(1007, 1224, 1585)
``````

Note: The function `is_primitive` is available to check if a Pythagorean triple is primitive:

``````julia> t = PythagoreanTriple(3,4,5)
PythagoreanTriple(3, 4, 5)

julia> is_primitive(t)
true

julia> t = PythagoreanTriple(30,40,50)
PythagoreanTriple(30, 40, 50)

julia> is_primitive(t)
false
``````

The function `make_primitive` takes a Pythagorean triple and returns a new triple having divided the three numbers by their greatest common divisor.

``````julia> t = PythagoreanTriple(6,8,10)
PythagoreanTriple(6, 8, 10)

julia> make_primitive(t)
PythagoreanTriple(3, 4, 5)
``````

### Scalar multiple

Pythagorean triples can be multiplied (on the left) by a positive integer. For example:

``````julia> p = PythagoreanTriple(5,12)
PythagoreanTriple(119, 120, 169)

julia> 10p
PythagoreanTriple(1190, 1200, 1690)
``````

### Finding parameters

All primitive Pythagorean triples (and some, but not all, non-primitive triples) can be constructed using two parameters `p = PythagoreanTriple(u,v)`.

Given such a triple, the function `get_parameters` will return a `u` and `v` that creates that triple.

``````julia> p = PythagoreanTriple(5,12,13)
PythagoreanTriple(5, 12, 13)

julia> u,v = get_parameters(p)
(2, 3)

julia> PythagoreanTriple(u,v)
PythagoreanTriple(5, 12, 13)
``````

While some non-primitive triples, such as `(6,8,10)`, can be created this way, others, such as `(30,40,50)`, cannot:

``````julia> p = get_parameters(6,8,10)
(1, 3)

julia> get_parameters(30,40,50)
ERROR: Unable to find parameters for (30, 40, 50) (non-primitive)
``````

## Extracting values

The function `make_tuple` returns a 3-tuple containing the three values:

``````julia> t = PythagoreanTriple(5,11)
PythagoreanTriple(96, 110, 146)

julia> make_tuple(t)
(96, 110, 146)
``````

## Sorting

Pythagorean triples can be compared using the usual `<`, `<=`, `>`, `>=` relations. Lists of triples can be sorted. They are sorted "reverse lexicographically". That is when we check if `(a,b,c)` is less than or equal to `(aa,bb,cc)` we first see if `c ≤ cc`. If so, then if `b ≤ bb`. And if so, then if `a ≤ aa`.

``````julia> list = collect(TripleGenerator(10))
10-element Vector{Any}:
PythagoreanTriple(3, 4, 5)
PythagoreanTriple(5, 12, 13)
PythagoreanTriple(8, 15, 17)
PythagoreanTriple(7, 24, 25)
PythagoreanTriple(20, 21, 29)
PythagoreanTriple(9, 40, 41)
PythagoreanTriple(12, 35, 37)
PythagoreanTriple(11, 60, 61)
PythagoreanTriple(28, 45, 53)
PythagoreanTriple(33, 56, 65)

julia> sort(list)
10-element Vector{Any}:
PythagoreanTriple(3, 4, 5)
PythagoreanTriple(5, 12, 13)
PythagoreanTriple(8, 15, 17)
PythagoreanTriple(7, 24, 25)
PythagoreanTriple(20, 21, 29)
PythagoreanTriple(12, 35, 37)
PythagoreanTriple(9, 40, 41)
PythagoreanTriple(28, 45, 53)
PythagoreanTriple(11, 60, 61)
PythagoreanTriple(33, 56, 65)
``````