Printing a result during a recursion in haskell - haskell

I am beginning to learn Haskell and am making a program to do the iterative process:
n -> n/2 (for even n)
n -> 3n+1 (for odd n)
So I got this far:`
chain n | n == 0 = error "What are you on about?"
| n == 1 = error "Finished"
| rem n 2 == 0 = chain (n `div` 2)
| rem n 2 /= 0 = chain (3 * n + 1)
`
Will this work?
But it only does the calculations behind the scenes, is there any way to make it display or export as list the result for n on each iteration until it reaches 1 so I can find the length of the list later?
On a side note, is there any way to make GHCi begin in a specific folder ?(I'm using windows)

You could have it return a list of the results in the "chain" like this:
chain n | n == 0 = error "What are you on about?"
| n == 1 = []
| rem n 2 == 0 = (n `div` 2) : chain (n `div` 2)
| otherwise = (3 * n + 1) : chain (3 * n + 1)
Now you'll get results like these:
*Main> chain 3
[10,5,16,8,4,2,1]
*Main> chain 7
[22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1]

Yes, certainly. There's even a function from the Data.List module that captures this usage pattern.
import Data.List (unfoldr)
chain 0 = []
chain n = unfoldr f n
where
f 1 = Nothing
f n = let n' | even n = n `div` 2
| otherwise = 3 * n + 1
in Just (n', n')
The type of unfoldr is: (b -> Maybe (a, b)) -> b -> [a]
b is the state variable that used to generate the list. The function supplied as the first argument to unfoldr should either returns Nothing (which means terminate the list) or Just (b, a) where a is the element to add to the list, and b is the new state variable.

is there any way to make it display or export as list the result for n on each iteration until it reaches 1
You can use the Debug.Trace.trace to print logging messages to stdout as values are evaluated. Good for quick debugging.

You will notice that the two earlier answers use the paradigm of "build the whole list, and then output it at the end" rather than "output one element at a time". This is the functional way of doing things.
If you really want to do it in an imperative style, you have to use monadic programming, which is a more advanced topic. Here's an example (don't worry if you can't understand everything that's going on ... monads are quite mysterious and magical):
import Control.Monad.Writer
chain :: Int -> (String, [Int])
chain = runWriter . chain'
where
chain' 0 = return "Failure"
chain' 1 = do
tell [1] -- write 1
return "Success" -- finished
chain' n = do
-- write n
tell [n]
-- calculate next n and recurse
if even n
then chain' $ n `div` 2
else chain' $ 3 * n + 1
Which gives results like:
*Main> chain 3
("Success",[3,10,5,16,8,4,2,1])
But, as you can see, the writer monad still just generates the list behind the scenes.
This might seem inefficient. What if you want to print a list of 1,000,000 elements? Do you really have to generate the whole list upfront? In fact, Haskell's lazy semantics mean that, whenever possible, Haskell will compile your "build the whole thing upfront and then print it out" code into "only generate and output one element at a time" code.

The function should just return the list of found elements. This list can be inspected further later on:
chain 0 = error "No no no."
chain 1 = [1]
chain n
| rem n 2 == 0 = n : chain (n `div` 2)
| otherwise = n : chain (3 * n + 1)
Here [1] is a list containing just 1 and : is a list constructor that adds the element on the left to the list on the right.
The list constructed by chain can then be displayed or used with other functions:
*Main> chain 5
[5,16,8,4,2,1]
*Main> length (chain 31)
107

Related

Prime Factorization in Haskell to return a list of tuples giving the number and the power

I have been trying to learn haskell by trying to do some simple problems.
The Problem
Currently, I am trying to implement a function primeFactorization :: Integer -> [(Integer, Integer)] such that the output is a list of tuples containing the prime factor and the power it is raise to in the number.
Example Output
> primeFactorization 120
[(2,3), (3,1), (5,1)] since 120 = 2^3 * 3^1 * 5^1
My (Partial) Solution
primeFactorization :: Integer -> [Integer]
primeFactorization n =
let
factors :: Integer -> [Integer]
factors n = [x | x <- [2..n-1], n `mod` x == 0]
isPrime :: Integer -> Bool
isPrime n
| n `elem` [0, 1] = False
| n == 2 = True
| n > 2 = null [ x | x <- [2..(ceiling . sqrt . fromIntegral) n], n `mod` x == 0]
| otherwise = False
in
filter isPrime $ (factors n)
This is a working implementation to get the prime factors of a number. However as seen it only outputs the prime factors. I am not sure on how to store the number of times in haskell. Also, considering it is un-idiomatic to iterate in haskell I don't know how I would implement the solution. In python, I would do:
def pf(number):
factors=[]
d=2
while(number>1):
while(number%d==0):
factors.append(d)
number=number/d
d+=1
return factors
So, the question: How to implement the powers of the prime factors?
NOTE:
I already saw: Prime factorization of a factorial however that does not answer my question.
This is NOT a homework problem, I am learning independently.
You can always replace imperative-language loops (as long as they don't meddle with any global state) with recursion. That may not be the most elegant approach, but in this case it seems perfectly appropriate to imitate your inner Python loop with a recursive function:
dividerPower :: Integer -> Integer -> Int
dividerPower n d
| n`rem`d == 0 = 1 + dividerPower (n`quot`d) d
| otherwise = 0
(This counts “backwards” compared to the Python loop. You could also make it tail-recursive with a helper function and count forwards over an accumulator variable, but that's more awkward and I don't think there's a memory/performance benefit that would justify it in this case.)
You can either use that together with your Haskell code (for each of the factors you've already found, check how often it occurs), or extend it so the whole thing works like the Python solution (which is actually a lot more efficient, because it avoids for every number checking whether it's prime). For that you just need to give back the final n in the result. Let's use a where block for handling the pattern matching, and also make the rem and:
dividePower :: Integer -> Integer -> (Integer, Int)
dividePower n d
| r == 0 = (nfin, p'+1)
| otherwise = (n, 0)
where (n', r) = n `quotRem` d
(nfin, p') = dividePower n' d
Then the equivalent to your Python code is
pf :: Integer -> Integer -> [(Integer, Int)]
pf = go 2
where go d n
| n>1 = (d, p) : go (d+1) n'
| otherwise = []
where (n', p) = dividePower n d
This actually gives you, like in Python, the list including also non-dividers (with power 0). To avoid that, change the list-building to
| n>1 = (if p>0 then ((d,p):) else id) $ go (d+1) n'

ruby while loop translated to haskell

I've just started learning a bit of Haskell and functional programming, but I find it very difficult getting a hang of it :)
I am trying to translate a small piece of ruby code to Haskell (because I like the concept functional programming and Haskell proposes and even more because I come from a mathematics field and Haskell seems very mathematical):
class Integer
def factorial
f = 1; for i in 1..self; f *= i; end; f
end
end
boundary = 1000
m = 0
# Brown Numbers - pair of integers (m,n) where n factorial is equal with square root of m
while m <= boundary
n = 0
while n <= boundary
puts "(#{m},#{n})" if ((n.factorial + 1) == (m ** 2))
n += 1
end
m += 1
end
I could only figure out how to do factorials:
let factorial n = product [1..n]
I cannot figure out how to do the while loops or equivalent in Haskell, even though I found some examples that were far to confusing for me.
The idea is that the loops start from 0 (or 1) and continue (with an increment of 1) until it reaches a boundary (in my code is 1000). The reason there is a boundary is because I was thinking of starting parallel tasks that do the same operation but on different intervals so the results that I expect are returned faster (one operation would be done on 1 to 10000, another on 10000 to 100000, etc.).
I would really appreciate it if anyone could help out with this :)
Try this:
let results = [(x,y) | x <- [1..1000], y <- [1..1000] ,1 + fac x == y*y]
where fac n = product [1..n]
This is a list comprehension. More on that here.
To map it to your Ruby code,
The nested loops in m and n are replaced with x and y. Basically there is iteration over the values of x and y in the specified ranges (1 to 1000 inclusive in this case).
The check at the end is your filter condition for getting Brown numbers.
where allows us to create a helper function to calculate the factorial.
Note that instead of a separate function, we could have computed the factorial in place, like so:
(1 + product[1..x]) == y * y
Ultimately, the (x,y) on the left side means that it returns a list of tuples (x,y) which are your Brown numbers.
OK, this should work in your .hs file:
results :: [(Integer, Integer)] --Use instead of `Int` to fix overflow issue
results = [(x,y) | x <- [1..1000], y <- [1..1000] , fac x == y*y]
where fac n = product [1..n]
To add to shree.pat18's answer, maybe an exercise you could try is to translate the Haskell solution back into Ruby. It should be possible, because Ruby has ranges, Enumerator::Lazy and Enumerable#flat_map. The following rewritten Haskell solution should perhaps help:
import Data.List (concatMap)
results :: [(Integer, Integer)]
results = concatMap (\x -> concatMap (\y -> test x y) [1..1000]) [1..1000]
where test x y = if fac x == y*y then [(x,y)] else []
fac n = product [1..n]
Note that Haskell concatMap is more or less the same as Ruby Enumerable#flat_map.

Haskell Mini Function Implementation

I have been trying to take this function and make small implementation using iterate and takeWhile. It doesn't have to be using those functions, really I'm just trying to turn it into one line. I can see the pattern in it, but I can't seem to exploit it without basically making the same code, just with iterate instead of recursion.
fun2 :: Integer -> Integer
fun2 1 = 0
fun2 n
| even n = n + fun2 (n `div` 2)
| otherwise = fun2 (3 * n + 1)
Any help would be great. I've been struggling with this for hours.
Thanks
If you want to do this with iterate, the key is to chop it up into smaller logical parts:
generate a sequence using the rule
ak+1 = ak/2 if ak even
ak+1 = 3ak+1 if ak odd
stop the sequence at aj = 1 (which all do, if the collatz conjecture is true).
filter out the even elements on the path
sum them
So then this becomes:
f = sum . filter even . takeWhile (>1) . iterate (\n -> if even n then n `div` 2 else 3*n + 1)
However, I do think this would be clearer with a helper function
f = sum . filter even . takeWhile (>1) . iterate collatz
where collatz n | even n = n `div` 2
| otherwise = 3*n + 1
This may save you no lines, but transforms your recursion into the generation of data.
Firstly, I agree with tom's comment that there is nothing wrong with your four line version. It's perfectly readable. However, it's occasionally a fun exercise to turn Haskell functions into one liners. Who knows, you might learn something!
At the moment you have
fun 1 = 0
fun n | even n = n + fun (n `div` 2)
| otherwise = fun (3 * n + 1)
You can always convert an expression using guards into an if
fun 1 = 0
fun n = if even n then n + fun (n `div` 2) else fun (3 * n + 1)
You can always convert a series of pattern matches into a case expression:
fun n = case n of
1 -> 0
_ -> if even n then n + fun (n `div` 2) else fun (3 * n + 1)
And finally, you can convert a case expression into a chain of ifs (actually, in general this would require an Eq instance for the argument of your function, but since you're using Integers it doesn't matter).
fun n = if n == 1 then 0 else if even n then n + fun (n `div` 2) else fun (3 * n + 1)
I think you'll agree that this is far less readable than what you started out with.
One liner ;)
fun2 n = if n==1 then 0 else if even n then n + fun2 (n `div` 2) else fun2 (3 * n + 1)
My sense is that short of look-up tables, this function cannot be implemented without recursion because the argument passed in the recursion seems unpredictable (except for n as powers of 2).
On the other hand, rampion helped me learn something new.

Haskell: Improving my tail-recursive fibonacci implementation

I have come up with the following tail-recursive fibonacci generator that works:
let {
fibo :: Integral x => [x]->x->x->x->[x]
fibo l x y 0 = l
fibo l x y n = fibo (l ++ [y+x] ++ [y+x+y]) (x+y) (y+x+y) (n-1)
}
Pardon me for the whole implementation put in one line because i am using the GHCi and haven't quite learnt how to put this in a file and run (i am yet to reach there). What i want to know is how this call:
fibo [0, 1] 0 1 5
can be improved. I do not want to pass the initial list with 0 and 1 and then pass 0 and 1 again with the limit. I believe that the implementation can be changed. What changes can be done?
Your algorithm is tail-recursive, but it looks like it has other drawbacks, namely 1) you are building the result list by appending to the end of it, and 2) it's not lazy.
For 1), note that when you append two lists a ++ b, you essentially have to reallocate a. In your case a is the growing list of fibonacci numbers and b are the next two terms. So each iteration reallocates the fibonacci numbers that have already been computed and adds on two more elements which will result in quadratic running time. It would be more efficient to prepend b to the front of a. You'll be producing the fibonacci numbers in reverse, but the running time will be linear. You can then reverse the list at the end if you want the sequence in ascending order.
Note that building the list in reverse order allows you to easily get at the last two terms of the sequence by using Code-Guru's pattern-matching idea.
For 2), note that you can't get the first element of the list until the entire computation has completed. Compare with the following lazy generation of the sequence:
fibs = 0 : (go 0 1)
where go a b = b : go b (a+b)
Even though it looks like the recursion never stops, fibs is only evaluated for as much as is needed. For example, fibs !! 3 only calls go a couple of times.
I'm not going to go to the algorithm itself, but here's some advice on how to structure your recursive functions.
First, here's how you would format your code in a separate file
fibo :: Integral x => [x]->x->x->x->[x]
fibo l x y 0 = l
fibo l x y n = fibo (l ++ [y+x] ++ [y+x+y]) (x+y) (y+x+y) (n-1)
If you save this as fibo.hs, then you can start GHCi with
ghci fibo.hs
to load the file at start. You can also load the file after starting GHCi with the command
:l fibo.hs
(assumming you start GHCi in the same directory where you saved fibo.hs)
Another nice feature is that now when you edit the file, you can reload all your changes by simply entering
:r
in the GHCi prompt.
Now, to get rid of the extra parameters, the usual pattern in Haskell is to refactor the recursive part to its own helper function and have the main function as an entry point that only takes the necessary parameters. For example,
fibo :: Integral x => x -> [x]
fibo n = fiboHelper [0,1] 0 1 n
fiboHelper :: Integral x => [x]->x->x->x->[x]
fiboHelper l x y 0 = l
fiboHelper l x y n = fiboHelper (l ++ [y+x] ++ [y+x+y]) (x+y) (y+x+y) (n-1)
Now you can call fibo simply with
> fibo 3
[0,1,1,2,3,5,8,13]
Also, a helper function like this that is not useful by itself is usually hidden inside the main function as an inner function using let or where.
fibo :: Integral x => x -> [x]
fibo n = fiboHelper [0,1] 0 1 n where
fiboHelper l x y 0 = l
fiboHelper l x y n = fiboHelper (l ++ [y+x] ++ [y+x+y]) (x+y) (y+x+y) (n-1)
An inner function like this is usually given a shorter name, because the context makes its purpose clear, so we could change the name to e.g. fibo'.
go is another commonly used name for a recursive helper function.
Just for the record: The "usual" definition for a list of Fibonacci numbers is:
fibo = 0 : scanl (+) 1 fibo

Iterating a function and analysing the result in haskell

Ok, referring back to my previous question, I am still working on learning haskell and solving the current problem of finding the longest chain from the following iteration:
chain n | n == 0 = error "What are you on about?"
| n == 1 = [1]
| rem n 2 == 0 = n : chain (n `div` 2)
| otherwise = n : chain (3 * n + 1)
I have this bit sorted, but I need to find the longest chain from a starting number below 1,000,000. So how do I make it do each starting number up to 1,000,000 and then print the one with the longest chain length.
I can do it for one example with:
Main> length (chain n)
I assume I need the output as an array and then use the maximum function to find the value largest chain length and then see how far along it is in the array of answers.
Is this a good way to go about finding a solution or is there a better way (perhaps with better efficiency)?
You are right about the maximum part. To get the list (that's what Haskell's []s are, arrays are different structures) you need to use the map higher-order function, like this:
chainLength n = length (chain n)
lengths = map chainLength [1..1000000]
Essentially, map takes as arguments a function and a list. It applies the function to each element in the list and returns the list of the results.
Since you will be needing the number whose chain has that length, you may want change the chainLength function to return the number as well, like this:
chainLength n = (n, length (chain n))
That way you will have an array of pairs, with each number and its chain length.
Now you need to get the pair with the largest second component. That's where the maximumBy function comes in. It works just like maximum but takes a function as a parameter to select how to compare the values. In this case, the second component of the pair. This comparison function takes two numbers and returns a value of type Ordering. This type has only three possible values: LT, EQ, GT, for less than, equal, and greater than, respectively.
So, we need a function that given two pairs tells us how the second components compare to each other:
compareSnd (_, y1) (_, y2) = compare y1 y2
-- Or, if you import Data.Function, you can write it like this (thanks alexey_r):
compareSnd = compare `on` snd -- reads nicely
I used the default compare function that compares numbers (well, not just numbers).
Now we only need to get the maximum using this function:
longestChain = maximumBy compareSnd lengths
That gets you a pair of the number with the longest chain and the corresponding length. Feel free to apply fst and snd as you please.
Note that this could be more much more concisely using zip and composition, but since you tagged the question as newbie, I thought it better to break it down like this.
SPOILER (solving the problem for positive integers under 100):
module Test where
import Data.List -- this contains maximumBy
chain n
| n == 0 = error "What are you on about?"
| n == 1 = [1]
| rem n 2 == 0 = n : chain (n `div` 2)
| otherwise = n : chain (3 * n + 1)
chains = map (\x -> (x,chain x)) [1..100]
cmpSnd (a,b) (c,d)
| length b > length d = GT
| length b == length d = EQ
| otherwise = LT
solve = (fst . maximumBy cmpSnd) chains
The chains function makes use of map. It applies a function to every element of a list of a values, so
map succ [1,2]
is the same as
[succ 1,succ 2]
The cmpSnd function is a comparison function that probably exists somewhere deep in the Hierarchical Libraries, but I could not find it, so I created it. GT means "the first value is greater than the second", the rest is trivial.
Solve takes the maximum (by utilizing the comparison function we defined earlier) of the list. This will be a pair of an integer and a list. It will return the integer only (because of the fst).
A comment: Your chain function is not tail-recursive. This means that large chains will inevitably result in a Stack Overflow. You shall add an explicit accumulator variable and make it tail-recursive.
Something like
fst $ maximumBy (length . snd) $ zip [1..1000000] $ map chain [1..1000000]
(untested)
i.e. don't work out how far along the longest chain is in the list of longest chains, but carry around the seed values with the chains instead.
I studied Haskell years ago, so I don't remember it that well. On the other hand I've tested this code and it works. You will get the max chain and the number that generates it. But as fiships has stated before, it will overflow for big values.
chain :: Int -> [Int]
chain n
| n == 0 = []
| n == 1 = [1]
| rem n 2 == 0 = n : chain (n `div` 2)
| otherwise = n : chain (3 * n + 1)
length_chain :: Int -> Int
length_chain n = length (chain n)
max_pos :: (Int,Int) -> Int -> [Int] -> (Int,Int)
max_pos (m,p) _ [] = (m,p)
max_pos (m,p) a (x:xs)
| x > m = max_pos (x,a) (a+1) xs
| otherwise = max_pos (m,p) (a+1) xs
The instruction will be
Main> max_pos (0,0) 1 (map length_chain [1..10000])
(262,6171)

Resources