Why this Haskell expression won't get a result? - haskell

I try to run this in GHCi:
take 100 [ (a,b,c) | a <- [1..], b <- [1..], c <- [1..], a^2 + b^2 == c^2, a<b ]
I would expect it to be calculated because of the lazyness of take, but that's not the case. Why?

You want the list for b to be related to c, and the list for a to be related to b.
The reason for this is a is started at 1, b is starting at 1, and then c is just counting up indefinitely. There are no triangles that have sides 1, 1, x>1.
A solution that should work would be
take 100 [(a,b,c) | c<-[1..], b<-[1..c], a<-[1..b], a^2 + b^2 == c^2]
This solution works because now a will count up from 1 to b, simultaneously, b will count up from 1 to c, and the c just counts up like normal.

It wont't work because you asking to generate triple in the following manner
[(1,1,1),(1,1,4),(1,1,9),(1,1,16),(1,1,25),(1,1,36),(1,1,49),(1,1,64),(1,1,81),(1,1,100),(1,1,121),(1,1,144),(1,1,169),(1,1,196),(1,1,225),(1,1,256),(1,1,289),(1,1,324),(1,1,361),(1,1,400),(1,1,441),(1,1,484),(1,1,529),(1,1,576),(1,1,625),(1,1,676),(1,1,729),(1,1,784),(1,1,841),(1,1,900),(1,1,961),(1,1,1024),(1,1,1089),(1,1,1156),(1,1,1225),(1,1,1296),(1,1,1369),(1,1,1444),(1,1,1521),(1,1,1600),(1,1,1681),(1,1,1764),(1,1,1849),(1,1,1936),(1,1,2025),(1,1,2116),(1,1,2209),(1,1,2304),(1,1,2401),(1,1,2500),(1,1,2601),(1,1,2704),(1,1,2809),(1,1,2916),(1,1,3025),(1,1,3136),(1,1,3249),(1,1,3364),(1,1,3481),(1,1,3600),(1,1,3721),(1,1,3844),(1,1,3969),(1,1,4096),(1,1,4225),(1,1,4356),(1,1,4489),(1,1,4624),(1,1,4761),(1,1,4900),(1,1,5041),(1,1,5184),(1,1,5329),(1,1,5476),(1,1,5625),(1,1,5776),(1,1,5929),(1,1,6084),(1,1,6241),(1,1,6400),(1,1,6561),(1,1,6724),(1,1,6889),(1,1,7056),(1,1,7225),(1,1,7396),(1,1,7569),(1,1,7744),(1,1,7921),(1,1,8100),(1,1,8281),(1,1,8464),(1,1,8649),(1,1,8836),(1,1,9025),(1,1,9216),(1,1,9409),(1,1,9604),(1,1,9801),(1,1,10000),(1,1,10201),(1,1,10404),(1,1,10609),(1,1,10816),(1,1,11025),(1,1,11236),(1,1,11449),(1,1,11664),(1,1,11881),(1,1,12100),(1,1,12321),(1,1,12544),(1,1,12769),(1,1,12996),(1,1,13225),(1,1,13456),(1,1,13689),(1,1,13924),(1,1,14161),(1,1,14400),(1,1,14641),(1,1,14884),(1,1,15129),(1,1,15376),(1,1,15625),(1,1,15876),(1,1,16129),(1,1,16384),(1,1,16641),(1,1,16900),(1,1,17161),(1,1,17424),(1,1,17689),(1,1,17956),(1,1,18225),(1,1,18496),(1,1,18769),(1,1,19044),(1,1,19321),(1,1,19600),(1,1,19881),(1,1,20164),(1,1,20449),(1,1,20736),(1,1,21025),(1,1,21316),(1,1,21609),(1,1,21904),(1,1,22201),(1,1,22500),(1,1,22801),(1,1,23104),(1,1,23409),(1,1,23716),(1,1,24025),(1,1,24336),(1,1,24649),(1,1,24964),(1,1,25281),(1,1,25600),(1,1,25921),(1,1,26244),(1,1,26569),(1,1,26896),(1,1,27225)
There is not bound for C, so haskell clearly never finds 100 triple such that 1^2 +1^2 = c^2.

Related

Haskell spitting out wrong numbers at random

I am just starting to learn functional programming, My pick is haskell.
It's been ok for a few days until something bizzare happen in the console
At first I thought the tutorial ( http://learnyouahaskell.com/starting-out ) is wrong
Prelude> [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]
[(1,1,1)]
It should be (3,4,5) and (4,6,8).
I tried 3^2+5^2, it spits out this bulks of numbers ( something like 60 rows of numbers, around 3000 digits ); 4^2+3^2 seems to produce the same numbers.
Trying to add any numbers the result will be 100
Prelude> 100 + 200
100
Prelude> 300 + 500
100
I close the window and re-open it and the problem is solved.
Does this miscalculation often happened in Haskell? or perhaps my version of Haskell is corrupted when downloading? or Any chance this is a rare bug?
What is happening, as #BluePeppers suggested, is that you have somehow done the equivalent of let a+b = 100 in ghci, after which it uses that definition instead of the usual + in all your expressions.
You might still wonder why that gives such enormous numbers, and so did I until I realized the second point: Redefining (+) also redefines its precedence, to the default of 9 (highest). So your examples become interpreted as:
[ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]
becomes
[ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^100^2 == c^2]
and
3^2+5^2
becomes
3^100^2

How are dependent ranges computed in a list comprehension?

I'm currently making my way through Learn You a Haskell for Great Good!, and I'm confused on the penultimate example in Chapter 2.
As a way of generating triples representing all right triangles with all sides that are whole numbers less than or equal to 10, he gives this definition:
rightTriangles = [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]
What I'm specifically confused about is the fact that b is bound to a list that ranges from 1 to c, and similarly with a. If my understanding is correct, c will be evaluated to all values in the list it is bound to, but I still don't see which value is being used for c in the range (e.g. all values of c, only the first c, etc.)
If it's not too much, a step by step explanation of how this evaluates would be great. :)
Thanks in advance!
Let's consider two simpler list comprehensions:
ex1 = [(a,b) | a <- [1..3], b <- [1..3]]
ex2 = [(a,b) | a <- [1..3], b <- [1..a]]
They're almost the same, but in the second case, b ranges from 1 to a, not 1 to 3. Let's consider what they're equal to; I've formatted their values in such a way as to make a point.
ex1 = [ (1,1), (1,2), (1,3)
, (2,1), (2,2), (2,3)
, (3,1), (3,2), (3,3) ]
ex2 = [ (1,1),
, (2,1), (2,2),
, (3,1), (3,2), (3,3) ]
In the first example, the list comprehension draws every possible combination of elements from [1..3] and [1..3]. But since we're talking about lists, not sets, the order it does that in is important. Thus, in more detail, what ex1 really means is this:
Let a be equal to every possible value from its list.
For each value of a, let b be every possible value from its list.
(a,b) is an element of the output list
Or, rephrased: "for every possible value of a, compute (a,b) for every possible value of b." If you look at the order of the results, this is what happens:
For the first three elements, a is equal to 1, and we see it paired with every value of b.
For the next three elements, a is equal to 2, and we see every value of b.
And finally, for the last three elements, a is equal to 3 and we see every value of b.
In the second case, much the same thing happens. But because a is picked first, b can depend on it. Thus:
First, a is equal to 1, and we see it paired with every possible value of b. Since b <- [1..a], that means b <- [1..1], and so there's only one option.
After one element, then, a is equal to 2, and we see that paired with every possible value of b. Now that means b <- [1..2], and so we get two results.
Finally, a is equal to 3, and so we're picking b <- [1..3]; this gives us the full set of three results.
In other words, because the list comprehensions rely on an ordering, you can take advantage of that. One way to see that is to imagine translating these list comprehensions into nested list comprehensions:
ex1 = concat [ [(a,b) | b <- [1..3]] | a <- [1..3] ]
ex2 = concat [ [(a,b) | b <- [1..a]] | a <- [1..3] ]
To get the right behavior, a <- [1..3] must go on the outside; this ensures that the bs change faster than the as. And it hopefully makes it clear how b can depend on a. Another translation (basically the one used in the Haskell 2010 Report) would be:
ex1 = concatMap (\a -> [(a,b) | b <- [1..3]]) [1..3]
= concatMap (\a -> concatMap (\b -> [(a,b)]) [1..3]) [1..3]
ex2 = concatMap (\a -> [(a,b) | b <- [1..a]]) [1..3]
= concatMap (\a -> concatMap (\b -> [(a,b)]) [1..a]) [1..3]
Again, this makes the nesting very explicit, even if it's hard to follow. Something to keep in mind is that if the selection of a is to happen first, it must be on the outside of the translated expression, even though it's on the inside of the list comprehension. The full, formal translation of rightTriangles would then be
rightTriangles =
concatMap (\c ->
concatMap (\b ->
concatMap (\a ->
if a^2 + b^2 == c^2
then [(a,b,c)]
else []
) [1..b]
) [1..c]
) [1..10]
As a side note, another way to write rightTriangles is as follows:
import Control.Monad (guard)
rightTriangles = do c <- [1..10]
b <- [1..c]
a <- [1..b]
guard $ a^2 + b^2 == c^2
return (a,b,c)
You probably haven't used do notation yet, and certainly not for anything but IO, so I'm not saying you should necessarily understand this. But you can read the x <- list lines as saying "for each x in list", and so read this as a nested loop:
rightTriangles = do
c <- [1..10] -- For each `c` from `1` to `10`, ...
b <- [1..c] -- For each `b` from `1` to `c`, ...
a <- [1..b] -- For each `a` from `1` to `b`, ...
guard $ a^2 + b^2 == c^2 -- If `a^2 + b^2 /= c^2`, then `continue` (as in C);
return (a,b,c) -- `(a,b,c)` is the next element of the output list.
Note that the continue only skips to the next iteration of the innermost loop in this interpretation. You could also write it as
rightTriangles = do c <- [1..10]
b <- [1..c]
a <- [1..b]
if a^2 + b^2 == c^2
then return (a,b,c)
else [] -- or `mzero`
Where the last lines say "if a^2 + b^2 == c^2, add (a,b,c) to the output list; otherwise, add nothing." I only mention this because I thought seeing it written this way might help make the "nested loop"-type structure that's going on clear, not because you should fully understand do-notation while reading Chapter 2 of Learn You A Haskell :-)
Seeing you have experience with imperative programming, a short answer would be: similar to this for nesting (pseudo code):
for(c = 1; c <= 10; c++) {
for(b = 1; b <= c; b++) {
for(a = 1; a <= b; a++) {
if(a ^ 2 + b ^ 2 == c ^ 2) {
list.append((a, b, c));
}
}
}
}

Which is a correct program for given statement?

Problem statement:
Find the right triangle that has integers for all sides and all sides equal to or smaller than 10 has a perimeter of 24.
Which solution of following two is correctly interpreting the problem and gives the right answer?
If the First Solution is not correct then how to avoid such programming error in similar scenario?
First Solution:
ghci> let rightTriangles = [(a, b, c) | a <- [1..10], b <- [1..10], c <- [1..10], a^2 + b^2 == c^2, a+b+c == 24]
ghci> rightTriangles
[(6,8,10),(8,6,10)]
Second Solution:
ghci> let rightTriangles' = [ (a,b,c) | c <- [1..10] , b <- [1..c] , a <- [1..b] , a^2 + b^2 == c^2, a+b+c == 24]
ghci> rightTriangles'
[(6,8,10)]
As it stands I think the problem is slightly under defined.
The first four words "Find the right triangle" (emphasis mine) suggests a unique answer, which is almost certainly meant to be (6,8,10). However the rest of the problem is met by all triangles that are congruent to (6,8,10), of which (8,6,10) is certainly one so it is not wrong per se, but probably not what you are meant to get.
Another way of looking at this is that the problem defines an equivalence class of which (6,8,10) is the canonical representation, however the problem does not explicitly ask for the canonical representation (though we can infer it is probably the expected answer and therefore should use your second solution)
You have to filter out different permutations. By restriction a <= b and b <= c, you can accomplish this. You did this in the second answer by restriction the input domain of b and c. b <- [1..c] implies b <= c.

Understanding A bit of Haskell

I have a quick question about Haskell. I've been following Learn You a Haskell, and am just a bit confused as to the execution order / logic of the following snippet, used to calculate the side lengths of a triangle, when all sides are equal to or less than 10 and the total perimeter of the triangle is 24:
[(a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2, a+b+c==24]
The part that is confusing to me is the upper expansion bound on the b and a binding. From what I gather, the ..c and ..b are used to remove additional permutations (combinations?) of the same set of triangle sides.
When I run it with the ..c/b, I get the answer:
[(6,8,10)]
When I don't have the ..c/b:
[(a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10], a^2 + b^2 == c^2, a+b+c==24]
as I didn't when I initially typed it in, I got:
[(8,6,10),(6,8,10)]
Which is obviously representative of the same triangle, save for the a and b values have been swapped.
So, can someone walk me through the logic / execution / evaluation of what's going on here?
The original version considers all triplets (a,b,c) where c is a number between 1 and 10, b is a number between 1 and c and a is a number between 1 and b. (6,8,10) fits that criteria, (8,6,10) doesn't (because here a is 8 and b is 6, so a isn't between 0 and 6).
In your version you consider all triplets (a,b,c) where a, b and c are between 1 and 10. You make no restrictions on how a, b and c relate to each other, so (8, 6, 10) is not excluded since all numbers in it are indeed between 1 and 10.
If you think of it in terms of imperative for-loops, your version does this:
for c from 1 to 10:
for b from 1 to 10:
for a from 1 to 10:
if a^2 + b^2 == c^2 and a+b+c==24:
add (a,b,c) to the result
while the original version does this:
for c from 1 to 10:
for b from 1 to c:
for c from 1 to b:
if a^2 + b^2 == c^2 and a+b+c==24:
add (a,b,c) to the result
It's not about execution order. In the first example you don't see the degenerate solution
[(8,6,10)]
since a <= b <= c. In the second case a > b is included in the list comprehension.
List comprehensions can be written in terms of other functions like concatMap, which clarifies the scope of the bindings. As a one-liner, your example becomes something like this:
concatMap (\c -> concatMap (\b -> concatMap (\a -> if a^2 + b^2 == c^2 then (if a+b+c == 24 then [(a,b,c)] else []) else []) (enumFromTo 1 b)) (enumFromTo 1 c)) (enumFromTo 1 10)
Yeah, that looks ugly, but it's similar to what Haskell desugars your comprehensions into. The scope of each of the variables a, b and c, should be obvious from this.
Or alternatively, this can be written with the List monad:
import Control.Monad
example = do c <- [1..10]
b <- [1..c]
a <- [1..b]
guard (a^2 + b^2 == c^2)
guard (a+b+c == 24)
return (a,b,c)
This is actually very similar as the one-liner above, given the definition of the List Monad and guard:
instance Monad [] where
return x = [x]
xs >>= f = concatMap f xs
instance MonadPlus [] where
mzero = []
mconcat = (++)
guard bool = if bool then return () else mzero

Pythagorean triple in Haskell without symmetrical solutions

I gotta do the Pythagorean triple in Haskell without symmetrical solutions. My try is:
terna :: Int -> [(Int,Int,Int)]
terna x = [(a,b,c)|a<-[1..x], b<-[1..x], c<-[1..x], (a^2)+(b^2) == (c^2)]
and I get as a result:
Main> terna 10
[(3,4,5),(4,3,5),(6,8,10),(8,6,10)]
As you can see, I´m getting symmetrical solutions like: (3,4,5) (4,3,5). I need to get rid of them but I don´t know how. Can anyone help me?
Every time you have a duplicate you have one version in which a is greater than b and one where b is greater than a. So if you want to make sure you only ever get one of them, you just need to make sure that either a is always equal to or less than b or vice versa.
One way to achieve this would be to add it as a condition to the list comprehension.
Another, more efficient way, would be to change b's generator to b <- [1..a], so it only generates values for b which are smaller or equal to a.
Speaking of efficiency: There is no need to iterate over c at all. Once you have values for a and b, you could simply calculate (a^2)+(b^2) and check whether it has a natural square root.
Don't know Haskell at all (perhaps you're learning it now?) but it seems like you could get rid of them if you could take only the ones for which a is less than or equal to b. That would get rid of the duplicates.
Try with a simple recursive generator:
http://en.wikipedia.org/wiki/Formulas_for_generating_Pythagorean_triples
(new article)
http://en.wikipedia.org/wiki/Tree_of_primitive_Pythagorean_triples
EDIT (7 May 2014)
Here I have made infinite generator that can generate primitive triplets ordered by perimeter (but can be modified to be ordered by other parameter - hypotenuses, area, ...) as long as it holds that any triplet is smaller that any generated from generator matrix according to provided compare function
import Data.List -- for mmult
merge f x [] = x
merge f [] y = y
merge f (x:xs) (y:ys)
| f x y = x : merge f xs (y:ys)
| otherwise = y : merge f (x:xs) ys
mmult :: Num a => [[a]] -> [[a]] -> [[a]]
mmult a b = [ [ sum $ zipWith (*) ar bc | bc <- (transpose b) ] | ar <- a ]
tpgen_matrix = [[[ 1,-2, 2],[ 2 ,-1, 2],[ 2,-2, 3]],
[[ 1, 2, 2],[ 2 , 1, 2],[ 2, 2, 3]],
[[-1, 2, 2],[-2 , 1, 2],[-2, 2, 3]]]
matrixsum = sum . map sum
tripletsorter x y = ( matrixsum x ) < ( matrixsum y ) -- compare perimeter
triplegen_helper b = foldl1
( merge tripletsorter )
[ h : triplegen_helper h | x <- tpgen_matrix , let h = mmult x b ]
triplets = x : triplegen_helper x where x = [[3],[4],[5]]
main = mapM print $ take 10 triplets
You can do the following:
pythagorean = [ (x,y,m*m+n*n) |
m <- [2..],
n <- [1 .. m-1],
let x = m*m-n*n,
let y = 2*m*n ]
This might work: Got it from this tutorial
triangles x = [(a,b,c) | c <- [1..x], b <- [1..c], a <- [1..b] , a^2 + b^2 == c^2]
List comprehension syntax makes this easy:
triplets :: Integer -> [(Integer, Integer, Integer)]
triplets d = [(a,b,c) | a <- [1..d], b <- [a..d], c <- [b..d], a^2 + b^2 == c^2]
This basically says than we build a list from as,bs and cs, where a changes from 1 to d, b changes from current a to d and etc. It also says that a^2 + b^2 == c^2 should hold.

Resources