Fibonacci Numbers in Haskell - haskell

Hi everbody I need to change my F# code to Haskell code but I am so new in Haskell and I can not this My code simply read data from keyboard if data not an integer return an error message then calculate the n fibonacci number then writes to a list after that writes the list into a txt file Here is my code
open System
let rec fib n =
match n with
|0->0
|1->1
|2->1
|n->fib(n-1)+fib(n-2);;
let printFibonacci list =
for i=0 to (List.length list)-1 do
printf "%d " (list.Item(i));;
let writeToFile list =
let file = System.IO.File.Create("C:\out2.txt")
let mutable s =""
let writer = new System.IO.StreamWriter(file)
try
for i=0 to (List.length list)-1 do
s <- list.Item(i).ToString()
writer.Write(s+" ")
finally
writer.Close()
file.Dispose()
printfn "Writed To File"
let mutable control = true
let mutable num = 0
while control do
try
printfn "Enter a Number:"
num <- Convert.ToInt32(stdin.ReadLine())
let listFibonacci = [for i in 0 .. num-1->fib(i)]
printFibonacci(listFibonacci)
printfn "\n%A"(listFibonacci)
writeToFile(listFibonacci)
control<-false
with
| :? System.FormatException->printfn "Number Format Exception";
Console.ReadKey true|>ignore

fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
main = do putStrLn "Enter a number:"
num <- readLn
fibs = map fib [0..n]
mapM' print fibs
However since haskell is lazy there is a clever way to define the list of all fibonacci numbers. And since you want a prefix of that list, it's more natural to use this definition (also more efficient):
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
main = do putStrLn "Enter a number:"
num <- readLn
mapM' print (take n fibs)
Edit: To write to a file instead of stdout replace print with (\num -> appendFile "filename" (show num)) or (appendFile "filename" . show).

That is basically the most common implementation of the sequence itself:
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
If you want the number from keyboard:
main :: IO ()
main = catch doFib handle
where doFib = do
num <- readLn
putStrLn $ "Fib of " ++ show num ++ " = " ++ (show . fib $ num)
handle _ -> putStrLn "Malformed input!"
Done!

Related

Outputting Pascal's triangle

import Data.List (intercalate)
import Control.Concurrent (threadDelay)
import System.IO
-- I love how amazingly concise Haskell code can be. This same program in C, C++ or Java
-- would be at least twice as long.
pascal :: Int -> Int -> Int
pascal row col | col >= 0 && col <= row =
if row == 0 || col == 0 || row == col
then 1
else pascal (row - 1) (col - 1) + pascal (row - 1) col
pascal _ _ = 0
pascalsTriangle :: Int -> [[Int]]
pascalsTriangle rows =
[[pascal row col | col <- [0..row]] | row <- [0..rows]]
main :: IO ()
main = do
putStrLn ""
putStr "Starting at row #0, how many rows of Pascal's Triangle do you want to print out? "
hFlush stdout
numRows <- (\s -> read s :: Int) <$> getLine
let triangle = pascalsTriangle numRows
triangleOfStrings = map (intercalate ", ") $ map (map show) triangle
lengthOfLastDiv2 = div ((length . last) triangleOfStrings) 2
putStrLn ""
mapM_ (\s -> let spaces = [' ' | x <- [1 .. lengthOfLastDiv2 - div (length s) 2]]
in (putStrLn $ spaces ++ s) >> threadDelay 200000) triangleOfStrings
putStrLn ""
My little program above finds the values of Pascal's Triangle. But if you compile it and use it you'll see that the "triangle" looks more like a Christmas tree than a triangle! Ouch!
I'm just taking half the length of the last line and subtracting from that half the length of each preceding line, and creating that many blank spaces to add to the beginning of each string. It ALMOST works, but I'm looking for an equilateral triangle type of effect, but to me it resembles a sloping Christmas tree! Is there a better way to do this. What am I missing besides some programming talent?! Thanks for the help. THIS IS NOT A HOMEWORK ASSIGNMENT. I'm just doing this for fun and recreation. I appreciate the help.
Best.
Douglas Lewit.
Here's a straightforward implementation:
space n = replicate n ' '
pad n s | n < length s = take n s
pad n s = space (n - length s) ++ s
triangle = iterate (\ xs -> zipWith (+) (xs ++ [0]) (0:xs)) [1]
rowPrint n hw xs = space (n * hw) ++ concatMap (pad (2*hw) . show) xs
triRows n hw = [rowPrint (n-i) hw row | (i,row) <- zip [1..n] triangle]
main = do
s <- getLine
mapM_ putStrLn (triRows (read s) 2)
Note that triangle is an infinite Pascal's triangle, generated by the recurrence relation. Also, hw stands for "half-width": half the width allocated for printing a number, and pad is a strict left-pad that truncates the output rather than disrupt the formatting.

putStrLn etc. not showing because of using map with a function which uses IO Monads?

I want to write a function which returns ten random numbers. The length of each random number corresponds to the nth Fibonacci number.
This is my code:
rndFib = do
let fibNumbers = map fib [0..9]
let bla = map printOneRndInt fibNumbers
putStrLn "All done"
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
printOneRndInt n = do
gen <- newStdGen
let randomInts = randomRs ('0','9') gen
(firstn, _) = splitAt n randomInts
putStrLn firstn
When I call rndFib, all I get is All done and none of the putStrLnlines are shown. I looks like they are returned into bla, but I just want them to be written out.
Any ideas are very welcome :)
You've defined an IO action under the name bla - but you never use it subsequently. So all your action rndFib actually does is print "all done".
To fix it, just put bla on a line of its own in the do block. And since this is a bit redundant, I would simply drop the let bla = from your version. This will also work as intended.

Infinite list parallel filter in Haskell

I want to find the first matching element in a infinite list in Haskell.
This code is working:
findPassword passwordHash = (head . filter (checkPassword passwordHash)) allStrings
checkPassword is really long (because it's a SHA1 hash)
checkPassword hash string = (sha1 string) == hash
allStrings is just the list of all possible strings:
allStrings = [ c : s | s <- "" : allStrings, c <- ['a'..'z'] ++ ['0'..'9'] ]
I want this code to be run in parallel but if I replace filter by parFilter:
import qualified Control.Parallel.Strategies as S
parFilter p = S.withStrategy (S.evalBuffer 1000 S.rseq) . filter p
It doesn't work… Do you have an idea? This code is also using a lot of memory but it's another problem.
The full script is available here https://github.com/ThibaudDauce/habreaker
I'm pretty sure you want to use parBuffer instead of evalBuffer.
See this SO answer for a good explanation:
How to choose between parList and parBuffer?
Here is some demo code:
import qualified Data.Map.Strict as M
import Control.Parallel.Strategies
import System.Environment
import Debug.Trace
fib 0 = 0
fib 1 = 1
fib n = fib (n-2) + fib (n-1)
fib' n | trace "calling fib" False = undefined
fib' n = fib n
theList = cycle [30,31,32]
firstN :: Int -> [Int]
firstN n = take n $ filter even $ map fib' theList
firstNpar :: Int -> Int -> [Int]
firstNpar n k = take n $ filter even $ runEval $ parBuffer k rseq $ map fib' theList
main = do
(argn : argk : _) <- getArgs
let n = read argn
case argk of
"" -> print $ firstN n
_ -> let k = read argk in
print $ firstNpar n k
Example runs:
prog 20 2 +RTS -N2 -- I only have two cores
prog 20 '' -- run single threaded

Simple Haskell program not behaving correct

I'm new to Haskell and trying to write simple program to find maximal element and it's index from intput. I receive values to compare one by one. Maximal element I'm holding in maxi variable, it's index - in maxIdx. Here's my program:
loop = do
let maxi = 0
let maxIdx = 0
let idx = 0
let idxN = 0
replicateM 5 $ do
input_line <- getLine
let element = read input_line :: Int
if maxi < element
then do
let maxi = element
let maxIdx = idx
hPutStrLn stderr "INNER CHECK"
else
hPutStrLn stderr "OUTER CHECK"
let idx = idxN + 1
let idxN = idx
print maxIdx
loop
Even though I know elements coming are starting from bigger to smaller (5, 4, 3, 2, 1) program enters INNER CHECK all the time (it should happen only for the first element!) and maxIdx is always 0.
What am I doing wrong?
Thanks in advance.
Anyway, let's have fun.
loop = do
let maxi = 0
let maxIdx = 0
let idx = 0
let idxN = 0
replicateM 5 $ do
input_line <- getLine
let element = read input_line :: Int
if maxi < element
then do
let maxi = element
let maxIdx = idx
hPutStrLn stderr "INNER CHECK"
else
hPutStrLn stderr "OUTER CHECK"
let idx = idxN + 1
let idxN = idx
print maxIdx
loop
is not a particularly Haskelly code (and as you know is not particularly correct).
Let's make if Haskellier.
What do we do here? We've an infinite loop, which is reading a line 5 times, does something to it, and then calls itself again for no particular reason.
Let's split it:
import Control.Monad
readFiveLines :: IO [Int]
readFiveLines = replicateM 5 readLn
addIndex :: [Int] -> [(Int, Int)]
addIndex xs = zip xs [0..]
findMaxIndex :: [Int] -> Int
findMaxIndex xs = snd (maximum (addIndex xs))
loop :: ()
loop = loop
main :: IO ()
main = do xs <- readFiveLines
putStrLn (show (findMaxIndex xs))
snd returns the second element from a tuple; readLn is essentially read . getLine; zip takes two lists and returns a list of pairs; maximum finds a maximum value.
I left loop intact in its original beauty.
You can be even Haskellier if you remember that something (huge expression) can be replaced with something $ huge expression ($ simply applies its left operand to its right operand), and the functions can be combined with .: f (g x) is the same as (f . g) x, or f . g $ x (see? it's working for the left side as well!). Additionally, zip x y can be rewritten as x `zip` y
import Control.Monad
readFiveLines :: IO [Int]
readFiveLines = replicateM 5 readLn
addIndex :: [Int] -> [(Int, Int)]
addIndex = (`zip` [0..])
findMaxIndex :: [Int] -> Int
findMaxIndex = snd . maximum . addIndex
main :: IO ()
main = do xs <- readFiveLines
putStrLn . show . findMaxIndex $ xs
As for debug print, there's a package called Debug.Trace and a function traceShow which prints its first argument (formatted with show, hence the name) to stderr, and returns its second argument:
findMaxIndex :: [Int] -> Int
findMaxIndex = snd . (\xs -> traceShow xs (maximum xs)) . addIndex
That allows you to tap onto any expression and see what's coming in (and what are the values around — you can show tuples, lists, etc.)
I think alf's answer is very good, but for what it's worth, here's how I would interpret your intention.
{-# LANGUAGE FlexibleContexts #-}
module Main where
import System.IO
import Control.Monad.State
data S = S { maximum :: Int
, maximumIndex :: Int
, currentIndex :: Int }
update :: Int -> Int -> S -> S
update m mi (S _ _ ci) = S m mi ci
increment :: S -> S
increment (S m mi ci) = S m mi (ci+1)
next :: (MonadIO m, MonadState S m) => m ()
next = do
S maxi maxIdx currIdx <- get
input <- liftIO $ getLine
let element = read input :: Int
if maxi < element
then do
modify (update element currIdx)
liftIO $ hPutStrLn stderr "INNER CHECK"
else
liftIO $ hPutStrLn stderr "OUTER CHECK"
modify increment
run :: Int -> IO S
run n = execStateT (replicateM_ n next) (S 0 0 0)
main :: IO ()
main = do
S maxi maxIdx _ <- run 5
putStrLn $ "maxi: " ++ (show maxi) ++ " | maxIdx: " ++ (show maxIdx)
This uses a monad transformer to combine a stateful computation with IO. The get function retrieves the current state, and the modify function lets you change the state.

Why do I get a parser error in my program?

I've written a Haskell program for problem 25 on Euler. I think my program should run and return the correct answer, but it doesn't:
-- Problem25.hs
module Main where
fib :: Int -> Integer
fib 1 = 1
fib 2 = 1
fib n = fib (n-1) + fib (n-2)
length1 :: Integer -> Int
length1 = length . show
main :: IO ()
main = do
list1 <- [1..]
list2 <- zip3 list1 list1 list1
list3 <- map funct list2
where funct u v w = (u, fib u, length1 (fib u))
putStrLn "number : " -- line 17
putStrLn $ show . head . ( dropWhile ( \(u,v,w)-> w < 1000 ) list3)
However, I get the following error:
$ ghc Problem25.hs
[1 of 1] Compiling Main ( Problem25.hs, Problem25.o )
Problem25.hs:17:3: parse error on input `putStrLn'
Why do I get the parser error? I'm in a do block, so putStrLn "number : " should be fine, right?
ok here is a version with all syntax errors removed:
module Main where
fib :: Int -> Integer
fib 1 = 1
fib 2 = 1
fib n = fib (n-1) + fib (n-2)
length1 :: Integer -> Int
length1 = length . show
main :: IO()
main = do
putStrLn "hello"
let liste = [1..]
let liste2 = zip3 liste liste liste
let liste3 = map funct liste2
putStrLn "number : "
putStrLn $ show . head $ (dropWhile ( \(_,_,w)-> w < 1000 ) liste3)
where funct (u,_,_) = (u,fib u,length1 (fib u))
as you can see there are quite a few:
where in the middle of a do block -> this has to go to the end
<- instead of let ... = ... - remember: <- is to pull out values form computations - in this case to get an a from an IO a
one . to many in the last putStrLn (the last part with dropWhile is a value not a function)
a few places where you have to use a 3-tuple argument instead of the curried version as you choose to go with zip3 (that returns tuples)
also note that while this compiles and runs it will most likely not be a good (or even feasible) solution - I did nothing more than remove your syntax problems - to get a good solution you should first work on your fib (which does not perform very well - there are better ways to compute it - hint: search for Haskell + Fib on your fav. search engine)
here are a few remarks:
you don't need the zip3 part with 3 times the same list - you can let your funct do this work (which btw: you already do - you ignore the second and third argument)
why do you dropWhile and then take the head? (filter and head seems more natural IMO)
of course you should also rethink the funct part (notice how you never need the middle item from the tuples?)
Good luck with the rest of the exercise ;)
a bit cleaned up
I cleaned up your solution a bit:
fib :: Int -> Integer
fib 1 = 1
fib 2 = 1
fib n = fib (n-1) + fib (n-2)
length1 :: Integer -> Int
length1 = length . show
solve :: Int
solve = head . filter ((>= 1000) . length1 . fib) $ [1..]
main :: IO()
main = do
putStrLn "number : "
print solve
that's still not better performance wise (that's your challange) but at least it works for 3 digits instead of 1000 (although even 10 will take quite some time with this ...)
enjoy
cannot help it
I had to try it and indeed if you define the sequence like this:
import Data.List (unfoldr)
fibs :: [Integer]
fibs = unfoldr fib (1,1)
where fib (n,m) = Just (n,(m,n+m))
(which is near to what you would usually do in a loop)
you get the answer rather quickly (4782)
of course you have to think about how to get the index to this (hint: now a zip might be a good idea)

Resources