Pythagorean trinity in Haskell using infinity lists

I want to generate pythagorean triples in Haskell using infinity lists. What is wrong with my code:

trojkaty = [(a,b,c) | a <- [1..], b <- [1..], c <- [1..], (a^2)+(b^2)==(c^2)] 
+6
source share
4 answers

Try to express the upper bounds for a and b in terms of an intermediate value of c , otherwise it will supplant the entire list of infinite values ​​before checking the last condition.

 trojkaty :: [(Int, Int, Int)] trojkaty = [(a,b,c) | c <- [2..], b <- [2..c-1], a <- [2..b-1], a^2 + b^2 == c^2] main = do print $ take 5 trojkaty 
+5
source

This will try to infinitely many values ​​of c for a=1 and b=1 , before he even tries b=2 .

One alternative option is to force this c >= a >= b :

  [(a,b,c) | c <- [1..], a <- [1..c], b <- [1..a], (a^2)+(b^2)==(c^2)] 
+2
source

Just for fun:

 Prelude Data.Universe> filter (\(a, b, c) -> a^2+b^2 == c^2 && all (>0) [a,b,c]) universe [(3,4,5),(4,3,5),(6,8,10),(8,6,10),(5,12,13),(12,5,13),(9,12,15),(12,9,15),... 

This requires a universe package.

+2
source

For completeness, another possibility is to use the so-called "diagonal monad", which tries the possibilities in a different order. There are several libraries for this.

(But for what you're trying to do, the accepted answer is probably much simpler / simpler.)

0
source

All Articles