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)
Related
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.
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
I am trying to compare the perf of two implementations of finding the Nth smallest number in a binary search tree. This is just a toy learning problem. My naïve attempt at measuring follows:
getNth :: Tree Int -> Int -> Either String Int
eval :: [Either b Int] -> Int
eval = (foldl (+) 0) . rights
main :: IO ()
main = do
let t = foldl treeInsertBalanced EmptyTree [1..1000000]
first = getNth t 100000
iterations = 100000000000
second = take iterations $ repeat $ getNth t 100
third = take iterations $ repeat $ getNth' t 100
print $ "dummy to cause eval: " ++ (show first)
print ""
time1 <- System.CPUTime.getCPUTime
print $ eval second
time2 <- System.CPUTime.getCPUTime
print $ eval third
time3 <- System.CPUTime.getCPUTime
let secondTime = time2-time1
thirdTime = time3-time2
timeDiff = secondTime - thirdTime
print $ "take version = " ++ (show secondTime)
print $ "opt version = " ++ (show thirdTime)
print $ "diff = " ++ (show timeDiff)
I am having a hard time figuring out how to include laziness where I want it, and prevent it where I do not.
I want the tree to be completely constructed before I begin measuring the functions that operate on it. This is why I try to force an evaluation of t by calling getNth on it and then printing it.
Is this doing what I hope it is doing.
Will t remain fully evaluated when I use it subsequently.
The difference in implementation between the two getNth functions is that the first uses the 'take' function on a simple depth first search of the tree. The second does a depth first search with an explicit early return. I want to know whether the simple 'take' implementation has to walk the whole tree or not. How can I determine that in a simpler way than measuring the performance of the two functions. I tried introducing an 'error' or an 'undefined' as a value in the tree, but of course neither was evaluated unless it was the Nth element in the tree. Is there another, simple way of determining whether the getNth function is truly laze or not?
(Available as a .lhs at http://pastebin.com/jpg0vSNd )
Some observations:
A good way to force evalution of a value is to use deepseq from Control.DeepSeq.
repeat does not re-evaluate it's argument.
GHC is pretty good at spotting expression which are the same, so sometimes you have to disguise your function calls with identical arguments to make GHC re-evalute the function call.
Here is an example of using deepseq:
import Control.DeepSeq (deepseq)
import Control.Monad
import Debug.Trace
import System.TimeIt
import System.Environment
theList = [1..8] ++ [undefined] ++ [10] :: [Int]
main1 = do
print $ length theList
print $ deepseq theList (length theList)
The first print statement emits 10. The second throws an exception because
the deepseq call tried to evaluate the undefined element.
To see that repeat does not re-evaluate it's argument, consider this example:
foo = repeat $ trace "(here)" 2
main2 = print $ take 3 foo
The result of running main2 is:
[(here)
2,2,2]
What is happening is that when the head of foo is called for repeat evaluate it's argument. This calls trace which prints (here) and returns 2. This value is saved by repeat when the rest of the list foo is needed.
Finally, here is a demonstration of how good GHC is at spotting function calls with identical arguemnts.
fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
theN = 34 -- use 24 if running under ghci
compute1 = fib theN
compute2 k = fib theN
compute3 k = fib (k+theN-k)
fib theN is just a function call which takes a while to compute (about 0.6 secs)
loop1 n = forM_ [1..n] $ \_ -> print compute1
loop2 n = forM_ [1..n] $ \k -> print (compute2 k)
loop3 n = forM_ [1..n] $ \k -> print (compute3 k)
timeLoop loop = do timeIt $ loop 1
timeIt $ loop 2
timeIt $ loop 3
timeIt $ loop 10
main4 = timeLoop loop1
main5 = timeLoop loop2
main6 = timeLoop loop3
main = do (arg:_) <- getArgs
case arg of
"4" -> main4
"5" -> main5
"6" -> main6
The run times depend on whether or not you compile with -O2 or not.
Typical reuts are:
w/o -O2 with -O2
main4 1 secs 0.1 sec
main5 13 secs 0.1 sec
main6 13 secs 1.0 sec
Some conclusions:
A top-level expression like compute1 is memoized.
Adding an ignored parameter (e.g. compute2) will fool GHC into recomputing a function call if -O2 is not used.
With -O2 a trickier way of disguising the function call may be needed to get GHC to re-evaluate it in a loop.
I hope this works by just pasting and running it with "runghc euler4.hs 1000". Since I am having a hard time learning Haskell, can someone perhaps tell me how I could improve here? Especially all those "fromIntegral" are a mess.
module Main where
import System.Environment
main :: IO ()
main = do
args <- getArgs
let
hBound = read (args !! 0)::Int
squarePal = pal hBound
lBound = floor $ fromIntegral squarePal /
(fromIntegral hBound / fromIntegral squarePal)
euler = maximum $ takeWhile (>squarePal) [ x | y <- [lBound..hBound],
z <- [y..hBound],
let x = y * z,
let s = show x,
s == reverse s ]
putStrLn $ show euler
pal :: Int -> Int
pal n
| show pow == reverse (show pow) = n
| otherwise = pal (n-1)
where
pow = n^2
If what you want is integer division, you should use div instead of converting back and forth to Integral in order to use ordinary /.
module Main where
import System.Environment
main :: IO ()
main = do
(arg:_) <- getArgs
let
hBound = read arg :: Int
squarePal = pal hBound
lBound = squarePal * squarePal `div` hBound
euler = maximum $ takeWhile (>squarePal) [ x | y <- [lBound..hBound],
z <- [y..hBound],
let x = y * z,
let s = show x,
s == reverse s ]
print euler
pal :: Int -> Int
pal n
| show pow == reverse (show pow) = n
| otherwise = pal (n - 1)
where
pow = n * n
(I've re-written the lbound expression, that used two /, and fixed some styling issues highlighted by hlint.)
Okay, couple of things:
First, it might be better to pass in a lower bound and an upper bound for this question, it makes it a little bit more expandable.
If you're only going to use the first two (one in your previous case) arguments from the CL, we can handle this with pattern matching easily and avoid yucky statements like (args !! 0):
(arg0:arg1:_) <- getArgs
Let's convert these to Ints:
let [a, b] = map (\x -> read x :: Int) [arg0,arg1]
Now we can reference a and b, our upper and lower bounds.
Next, let's make a function that runs through all of the numbers between an upper and lower bound and gets a list of their products:
products a b = [x*y | x <- [a..b], y <- [x..b]]
We do not have to run over each number twice, so we start x at our current y to get all of the different products.
from here, we'll want to make a method that filters out non-palindromes in some data set:
palindromes xs = filter palindrome xs
where palindrome x = show x == reverse $ show x
finally, in our main function:
print . maximum . palindromes $ products a b
Here's the full code if you would like to review it:
import System.Environment
main = do
(arg0:arg1:_) <- getArgs
let [a, b] = map (\x -> read x :: Int) [arg0,arg1]
print . maximum . palindromes $ products a b
products a b = [x*y | x <- [a..b], y <- [x..b]]
palindromes = filter palindrome
where palindrome x = (show x) == (reverse $ show x)
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!