Trouble using map in Haskell - haskell

I am attempting to make an algorithm to solve Project Euler Problem 255
I came up with this solution:
roundedSq n | (roundedSq n) == roundedSq (n-1) = n : roundedSq (n+1)
| rem n 2 == 1 = n : floor ( ((2*10^((d-1) `div` 2)) + ceiling (n `div` (2*10^((d-1) `div` 2)) )) `div` 2 )
| otherwise = n : floor ( ((7*10^((d-2) `div` 2)) + ceiling (n `div` (7*10^((d-2) `div` 2)) )) `div` 2 )
where
d = length (map (digitToInt) (show (n)))
average a = (sum a) `div` (length a)
answer = average [map roundedSq [10E13..10E14]]
main = do
print answer
But every time I try to load, it comes with an error for the answer calculating function.
What have I done wrong and will this even give me a correct solution or will it just get stick in a loop??

answer = average [map roundedSq [10E13..10E14]]
You've put the mapped list into a list of one element here. I think perhaps you mean:
answer = average (map roundedSq [10E13..10E14])

There is a problem with your average.
average a = (sum a) `div` (length a)
sum uses the entire list. length also uses the entire list. This means that the whole list will be generated and held in memory while one of these functions traverses it, and will not be garbage collected until the other function traverses it.
You pass average a very large list, so you will run out of memory.
Solution: rewrite average as a function that only traverses the list once, so that the list can be garbage collected as it is generated.
Example (untested):
average a = sum `div` length
where (sum, length) = foldl' f (0, 0) a
f (sum, length) i = (sum + i, length + 1)
Note that this uses foldl', from Data.List, not foldl. foldl has its own space issues (which someone more knowledgeable than me may wish to comment on).
And as Tobias Wärre has pointed out,
roundedSq n | (roundedSq n) == roundedSq (n-1) = n : roundedSq (n+1)
will result in an endless loop:
we want to evaluate roundedSq n
if (roundedSq n) == roundedSq (n-1) is true, we will return n : roundedSq (n+1) as the answer
we need to evaluate (roundedSq n) == roundedSq (n-1)
we need to evaluate roundedSq n
goto 1.

If you want average to return a Fractional number you'll need to use this definition:
average a = (sum a) / (fromIntegral $ length a)
(/) is the Fractional division operator whereas div is the Integral division operator. Note you also need to use fromIntegral because length returns an Int which is not a part of the Fractional type class.

You'll get stuck in an infinite loop due to
roundedSq n | (roundedSq n) ...
Edit: Sometimes it seems like I have a hole in my head. Of course average is ok.
However, since you don't decrement or increment all recursive calls to roundedSq you will never hit the "bottom" and terminate.

Related

Haskell primes number sequence recursion

I need to make a function primes which is not taking any parameter and returns me the list of all the prime numbers.
This is the code I came up with:
isqrt = floor . sqrt . fromIntegral
primes = 2:3:(primes' 4)
primes' n =
if (all(\y-> (y < isqrt n) && ((n `mod` y) /= 0)) primes)
then
n:primes' (n+1)
else
primes` (n+1)
The program prints only 2:3: and then it stops.
Shouldn't this work because of the lazy evaluation? (by taking primes as the list constructed until now and be able to see if my current number is divisible by any of the numbers in that list and then if yes append it and continue the recursion, if not keep going).
Can anyone please point me towards my mistake?
Some points: technically, your program does not print anything. Second, it does not even compile — notice a typo in the last line.
As for your question: in your function you call all on the infinite list primes, and all tries to traverse all of it — that's why the program hangs. You need to take only the elements you need from primes and only then apply all. For example:
isqrt = floor . sqrt . fromIntegral
primes = 2:3:(primes' 4)
primes' n =
if (all (\y-> (n `mod` y) /= 0) (takeWhile (<= isqrt n) primes))
then
n:primes' (n+1)
else
primes' (n+1)
main = print (take 5 primes)
Edit: using takeWhile as #behzad.nouri suggests.

Expressing recursion in Haskell - Prime numbers sequence

I need to express the sequence of prime numbers. (struggling with ex 3 in project Euler).
I have happened to this recursive definition:
is_not_dividable_by :: (Integral a) => a -> a -> Bool
is_not_dividable_by x y = x `rem` y /= 0
accumulate_and :: (Integral a) => [a] -> (a -> Bool) -> Bool
accumulate_and (x:xs) (f) = (accumulate_and xs (f)) && f(x)
accumulate_and [] f = True
integers = [2,3..]
prime_sequence = [n | n <- integers, is_prime n]
where is_prime n = accumulate_and
(takeWhile (<n) (prime_sequence))
( n `is_not_dividable_by`)
result = take 20 prime_sequence
str_result = show result
main = putStrLn str_result
Though it compiles well, but when executed, it falls into a loop, and just returns <<loop>>
My problem is that I think that I can freely express recursive definitions in Haskell.
But obviously this definition does not fit with the language at all.
However, when I mentally try to solve the prime_sequence, I think I succeed and grow the sequence, but of course with imperative programming apriori.
What is plain wrong in my recursive definition, that makes this code not work in Haskell ?
The culprit is this definition:
prime_sequence = [n | n <- [2,3..], is_prime n] where
is_prime n = accumulate_and
(takeWhile (< n) (prime_sequence))
( n `is_not_dividable_by`)
Trying to find the head element of prime_sequence (the first of the 20 to be printed by your main) leads to takeWhile needing to examine prime_sequence's head element. Which leads to a takeWhile call needing to examine prime_sequence's head element. And so it goes, again and again.
That's the black hole, right away. takeWhile can't even start walking along its input, because nothing's there yet.
This is fixed easily enough by priming the sequence:
prime_sequence = 2 : [n | n <- [3,4..], is_prime n] where
is_prime n = accumulate_and
(takeWhile (< n) (prime_sequence))
( n `is_not_dividable_by`)
Now it gets to work, and hits the second problem, described in Rufflewind's answer: takeWhile can't stop walking along its input. The simplest fix is to stop at n/2. But it is much better to stop at the sqrt:
prime_sequence = 2 : [n | n <- [3,4..], is_prime n] where
is_prime n = accumulate_and
(takeWhile ((<= n).(^ 2)) (prime_sequence))
( n `is_not_dividable_by`)
Now it should work.
The reason it's an infinite loop is because of this line:
prime_sequence =
[n | n <- integers, is_prime n]
where is_prime n = accumulate_and (takeWhile (< n) prime_sequence)
(n `is_not_dividable_by`)
In order to compute is_prime n, it needs to take all the prime numbers less than n. However, in order for takeWhile to know when to stop taking it needs need to also check for n, which hasn't been computed yet.
(In a hand-wavy manner, it means your prime_sequence is too lazy so it ends up biting its own tail and becoming an infinite loop.)
Here's how you can generate an infinite list of prime numbers without running into an infinite loop:
-- | An infinite list of prime numbers in ascending order.
prime_sequence :: [Integer]
prime_sequence = find [] integers
where find :: [Integer] -> [Integer] -> [Integer]
find primes [] = []
find primes (n : remaining)
| is_prime = n : find (n : primes) remaining
| otherwise = find primes remaining
where is_prime = accumulate_and primes (n `is_not_dividable_by`)
The important function here is find, which takes an existing list of primes and a list of remaining integers and produces the next remaining integer that is prime, then delays the remaining computation until later by capturing it with (:).

Setting upper limit to the input set according to the output function

I'm currently stuck on setting upper limits in list comprehensions.
What I'm trying to do is to find all Fibonacci numbers below one million.
For this I had designed a rather simple recursive Fibonacci function
fib :: Int -> Integer
fib n
n == 0 = 0
n == 1 = 1
otherwise = fib (n-1) + fib (n-2)
The thing where I'm stuck on is defining the one million part. What I've got now is:
[ fib x | x <- [0..35], fib x < 1000000 ]
This because I know that the 35th number in the Fibonacci sequence is a high enough number.
However, what I'd like to have is to find that limit via a function and set it that way.
[ fib x | x <- [0..], fib x < 1000000 ]
This does give me the numbers, but it simply doesn't stop. It results in Haskell trying to find Fibonacci numbers below one million further in the sequence, which is rather fruitless.
Could anyone help me out with this? It'd be much appreciated!
The check fib x < 1000000 in the list comprehension filters away the fib x values that are less than 1000000; but the list comprehension has no way of knowing that greater values of x imply greater value of fib x and hence must continue until all x have been checked.
Use takeWhile instead:
takeWhile (< 1000000) [ fib x | x <- [0..35]]
A list comprehension is guaranteed to look at every element of the list. You want takeWhile :: (a -> Bool) -> [a] -> [a]. With it, your list is simply takeWhile (< 1000000) $ map fib [1..]. The takeWhile function simply returns the leading portion of the list which satisfies the given predicate; there's also a similar dropWhile function which drops the leading portion of the list which satisfies the given predicate, as well as span :: (a -> Bool) -> [a] -> ([a], [a]), which is just (takeWhile p xs, dropWhile p xs), and the similar break, which breaks the list in two when the predicate is true (and is equivalent to span (not . p). Thus, for instance:
takeWhile (< 3) [1,2,3,4,5,4,3,2,1] == [1,2]
dropWhile (< 3) [1,2,3,4,5,4,3,2,1] == [3,4,5,4,3,2,1]
span (< 3) [1,2,3,4,5,4,3,2,1] == ([1,2],[3,4,5,4,3,2,1])
break (> 3) [1,2,3,4,5,4,3,2,1] == ([1,2,3],[4,5,4,3,2,1])
It should be mentioned that for such a task the "canonical" (and faster) way is to define the numbers as an infinite stream, e.g.
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
takeWhile (<100) fibs
--[0,1,1,2,3,5,8,13,21,34,55,89]
The recursive definition may look scary (or even "magic") at first, but if you "think lazy", it will make sense.
A "loopy" (and in a sense more "imperative") way to define such an infinite list is:
fibs = map fst $ iterate (\(a,b) -> (b,a+b)) (0,1)
[Edit]
For an efficient direct calculation (without infinite list) you can use matrix multiplication:
fib n = second $ (0,1,1,1) ** n where
p ** 0 = (1,0,0,1)
p ** 1 = p
p ** n | even n = (p `x` p) ** (n `div` 2)
| otherwise = p `x` (p ** (n-1))
(a,b,c,d) `x` (q,r,s,t) = (a*q+b*s, a*r+b*t,c*q+d*s,c*r+d*t)
second (_,f,_,_) = f
(That was really fun to write, but I'm always grateful for suggestions)
The simplest thing I can think of is:
[ fib x | x <- [1..1000000] ]
Since fib n > n for all n > 3.

Haskell prime test

I'm new to Haskell, and I'm trying a bit:
isPrime :: Integer->Bool
isPrime x = ([] == [y | y<-[2..floor (sqrt x)], mod x y == 0])
I have a few questions.
Why when I try to load the .hs, WinHugs say: Instances of (Floating Integer, RealFrac Integer) required for definition of isPrime?
When the interpreter finds one element in the right set, it immediately stops or it computes all the set? I think you know what I mean.
Sorry about my english.
1) The problem is that sqrt has the type (Floating a) => a -> a, but you try to use an Integer as argument. So you have to convert your Integer first to a Floating, e.g. by writing sqrt (fromIntegral x)
2) I see no reason why == shouldn't be lazy, but for testing for an empty collection you can use the null function (which is definitely lazy, as it works on infinite lists):
isPrime :: Integer->Bool
isPrime x = null [y | y<-[2..floor (sqrt (fromIntegral x))], x `mod` y == 0]
But in order to get an more idiomatic solution, break the problem into smaller sub-problems. First, we need a list of all elements y with y*y <= x:
takeWhile (\y -> y*y <= x) [2..]
Then we need only the elements that divide x:
filter (\y -> x `mod`y == 0) (takeWhile (\y -> y*y <= x) [2..])
Then we need to check if that list is empty:
isPrime x = null (filter (\y -> x `mod`y == 0) (takeWhile (\y -> y*y <= x) [2..]))
And if this looks to lispy to you, replace some of the parens with $
isPrime x = null $ filter (\y -> x `mod` y == 0) $ takeWhile (\y -> y*y <= x) [2..]
For additional clarity you can "outsource" the lambdas:
isPrime x = null $ filter divisible $ takeWhile notTooBig [2..] where
divisible y = x `mod`y == 0
notTooBig y = y*y <= x
You can make it almost "human readable" by replacing null $ filter with not $ any:
isPrime x = not $ any divisible $ takeWhile notTooBig [2..] where
divisible y = x `mod`y == 0
notTooBig y = y*y <= x
Because sqrt has the type Floating a => a -> a. This means the input has to be a Floating type and the output will be the same type. In other words x needs to be a Floating type. However you declared x to be of type Integer, which is not a Floating type. In addition floor needs a RealFrac type, so x needs to be that as well.
The error message suggests that you fix that by making Integer a Floating type (by defining an instance Floating Integer (and the same for RealFrac).
Of course this is not the correct approach in this case. Rather you should use fromIntegral to convert x to a Real (which is an instance of Floating and RealFrac) and then give that to sqrt.
Yes. As soon as == sees that the right operand has at least one element, it knows it is not equal to [] and thus returns False.
That being said, null is a more idiomatic way to check whether a list is empty than [] ==.
Regarding the second point, it stops, for example:
[] == [x | x <- [1..]]
Returns False
Landei's solution is great, however, if you want a more efficient¹ implementation we have (thanks to BMeph):
-- list of all primes
primes :: [Integer]
primes = sieve (2 : 3 : possible [1..]) where
sieve (p : xs) = p : sieve [x | x <- xs, x `mod` p > 0]
possible (x:xs) = 6*x-1 : 6*x+1 : possible xs
isPrime :: Integer -> Bool
isPrime n = shortCircuit || (not $ any divisible $ takeWhile inRangeOf primes) where
shortCircuit = elem n [2,3] || (n < 25 && ((n-1) `mod` 6 == 0 || (n+1) `mod` 6 == 0))
divisible y = n `mod` y == 0
inRangeOf y = y * y <= n
The 'efficiency' comes from the use of constant primes. It improves the search in two ways:
The Haskell runtime could cache the results so subsequent invocations are not evaluated
It eliminates a range of numbers by logic
note that the sieve value is simply a recursive table, where says the head of
the list is prime, and adds it to it. For the rest of the lists if there is no
other value already in the list that composes the number then its also prime
possible is list of all possible primes, since all possible primes are in the
form 6*k-1 or 6*k-1 except 2 and 3
The same rule is applied for shortCircuit too to quickly bail out of calculations
Footnote by D.F.
¹ It's still a terribly inefficient way to find primes. Don't use trial division if you need primes larger than a few thousand, use a sieve instead. There are several far more efficient implementations on hackage.
I think WinHugs needs to import a module for Integer and etc... Try Int
The interpreter will not compute anything until you call e.g. isPrime 32 then it will lazily compute the expression.
PS your isPrime implementation is not the best implementation!

Error "No instance for (Num [t])" in Collatz function

I am new to Haskell, and programming in general. I am trying to define a function which generates the sequence of Collatz numbers from n. I have:
collatz n = (collatz' n) : 1
where collatz' n = (takeWhile (>1) (collatz'' n))
where collatz'' n = n : collatz'' (collatz''' n)
where collatz''' 1 = 1
collatz''' n = if (even n) then (div n 2) else ((3*2)+1)
When I run this in GHCi, I get the error:
No instance for (Num [t])
arising from the literal `2' at <interactive>:1:7
Possible fix: add an instance declaration for (Num [t])
I don't know what this means. The problem seems to be appending "1" to the list. This problem emerges because
collatz' n = (takeWhile (>0) (collatz'' n))
generates an infinite sequence of "1"s following the correct Collatz sequence; however,
collatz' n = (takeWhile (>1) (collatz'' n))
generates all Collatz numbers from n except "1". What am I doing wrong?
(:) :: a -> [a] -> [a]
Your first line collatz n = (collatz' n) : 1 forces 1 to become [a].
I guess you wanted something like (collatz' n) ++ [1]
And you have error in if (even n) then (div n 2) else ((3*2)+1) there should be ((3*n)+1 or something like that else you have collatz''' 7 = 7
ony's answer is correct, but since you're new to Haskell, maybe this is a clearer explanation. The : operator prepends a value to a list, so doing somelist : 7 is invalid since that's trying to append a value to a list. That's why (collatz' n) : 1 doesn't compile, since the type of (collatz' n) is a list of numbers.
Try replacing the : 1 with ++ [1].
Another way to go at the problem may be for you to use a Data.Sequence structure instead of a list. Sequences allow you to "snoc" a value (put a value on the back of a sequence) as well as the more usual "cons" (put it on the front of the sequence).
Another solution for you may be to use span to make your own "takeUntil" function.
Let me explain: span p xs gives you the same answer as (takeWhile p xs, dropWhile p xs) for whichever p function and xs list you'd use, the same way that splitAt n xs is the same as (take n xs, drop n xs).
Anyway, you can use span to make your own "takeUntil" function:
takeUntil p xs = taken ++ take 1 dropped where
(taken, dropped) = span p xs
This is the form that you were looking for, when you used the collatz n = (collatz' n) : 1 form.
I hope this helps.

Resources