Which is a correct program for given statement? - haskell
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.
Related
Exponentiation using list comprehension
I'm trying to solve the following exercise (I'm learning Haskell): Define x^n using a list comprehension. And I'm struggling to find a solution. Using recursion or fold, the solution is not complicated (for instance, foldr (*) 1 [x | c <- [1..n]]). However, using only list comprehension it gets difficult (at least for me). In order to solve the problem, I'm trying to create a list of x^n elements and then get the length. Generating a list of x*n elements is easy, but I fail to generate a list of x^n elements. ppower x n = length [1 | p <- [1..x], c <- [1..n]] returns a list of x*n elements giving a wrong result. Any ideas on this will be appreciated.
A naturally-occurring exponential comes from sequence: length (sequence [[1..x] | _ <- [1..n]]) If you haven't seen sequence yet, it's quite a general function but when used with lists it works like: sequence [xs1, ... , xsk] = [[x1, ... xk] | x1 <- xs1, ... , xk <- xsk] But this is really cheating since sequence is defined recursively. If you want to use nothing but length and list comprehensions I think it might be impossible. The rest of this answer will be sketchy and I half expect someone to prove me wrong. However: We'll try to prove that such an expression can only compute values up to some finite power of x or n, and therefore can't compute values as big as x^n for arbitrary x and n. Specifically we show by induction on the structure of expressions that any expression expr has an upper bound ub(expr, m) = m^k where m is the maximum of the free variables it uses, and k is a known finite power which we could calculate from the structure of the expression expr. (When we look at the whole expression, m will be max x n.) Our upper bounds on list expressions will be bounds on both the length of the list and also bounds on any of its elements (and lengths of its elements, etc.). For example if we have [x..y] and we know that x <= m and y <= m, we know that all the elements are <= m and the length is also <= m. So we have ub([x..y], m) = m^1. The tricky case is the list comprehension: [eleft | x1 <- e1, ... , xk <- ek] The result will have length equal to length e1 * ... * length ek, so an upper bound for it would be the product of the upper bounds for e1 to ek, or if m^i is the maximum of these then an upper bound would be (m^i)^k = m^(i*k). To get a bound on the elements, suppose expression eleft has ub(eleft, m') = m'^j. It can use x1 ... xk. If m^i is an upper bound for these, as above, we need to take m' = m^i and so ub(eleft, m) = (m^i)^j = m^(i*j) As a conservative upper bound for the whole list comprehension e we could take ub(e, m) = m^(i*j*k). I should really also work through cases for pattern matching (shouldn't be a problem because the parts matched are smaller than what we already had), let definitions and functions (but we banned recursion, so we can just fully expand these before we start), and list literals like [x,37,x,x,n] (we can throw their lengths into m as initially-available values). If infinite lists like [x..] or [x,y..] are allowed they would need some thinking about. We can construct head and filter, which means we can get from an infinite list to its first element matching a predicate, and that looks suspiciously like a way to get recursive functions. I don't think it's a problem since 1. they are only arithmetic sequences and 2. we'll have to construct any numbers we want to use in the predicate. But I'm not certain here.
As #n.m suggested, I asked Richard Bird (author of the book "Introduction to functional programming", first edition, the book where I got the exercise) for an answer/guidance in solving this exercise. He kindly replied and here I post the answer he gave me: Since a list comprehension returns a list not a number, x^n cannot be defined as an instance of a list comprehension. Your solution x^n = product [x | c <- [1..n]] is the correct one. So, I guess I'll stick to the solution I posted (and discarded for using recursion): foldr (*) 1 [x | c <- [1..n]] He didn't say anything about creating a list of x^n elements with lists comprehensions (no recursion) though as #David Fletcher and #n.m point out in their comments, it might be impossible.
May be you can do as follows; pow :: Int -> Int -> Int pow 0 _ = 1 pow 1 x = x pow n x = length [1 | y <- [1..x], z <- [1..pow (n-1) x]] so pow 3 2 would return 8
Why this Haskell expression won't get a result?
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.
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)); } } } }
Why can't a list be defined like this in Haskell?
[(a,b) | a <- [1..5], b <- [1..5], a+b <- [1..10] ] Trying to define define a list that follows these rules. I know it doesn't allow the way I am adding a and b but I don't understand why. Edited forgot the "<-"
Maybe you want this? [(a,b) | a <- [1..5], b <- [1..5], a + b >= 1 && a + b <= 10] Or this? [(a,b) | a <- [1..5], b <- [1..5], a + b `elem` [1..10]] Haskell doesn't solve equations for you, it performs calculations. This declares the values which a variable takes: a <- [1..5] This is a request for Haskell to solve an equation, which it doesn't do... the left side has to be a valid pattern. a + b <- [1..10] # Not valid Haskell Of course, patterns can be more sophisticated, > [a | Just a <- [Just 10, Nothing, Just 20]] [10, 20]
The "<-" in a list comprehension actually draws elements from a list. Your third expression, "a+b <- [1..10]" is really trying to express that the sum could be drawn from a list. That's a job for (elem), a predicate, or test. elem :: (Eq a) => a -> [a] -> Bool A pretty good way to think about the problem is, how would it be implemented? You'd have to take elements, then test to see if they met the criteria. I'd use a predicate like elem (a + b) [1..10] to test that.