我为problem 25 on Euler编写了一个Haskell程序。我认为我的程序应该运行并返回正确的答案,但它没有:
-- 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)
但是,我收到以下错误:
$ ghc Problem25.hs [1 of 1] Compiling Main ( Problem25.hs, Problem25.o ) Problem25.hs:17:3: parse error on input `putStrLn'
为什么我会收到解析器错误?我在do
区块,所以putStrLn "number : "
应该没问题,对吗?
答案 0 :(得分:2)
这是一个删除了所有语法错误的版本:
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))
你可以看到有很多:
where
位于do
块的中间 - &gt;这必须走到尽头<-
而非let ... = ...
- 请记住:<-
是从计算中提取值 - 在这种情况下,从a
获取IO a
.
putStrLn
中有一个dropWhile
到多个(zip3
的最后一个部分是值而不是函数)fib
(返回元组)还要注意,虽然这个编译并运行它很可能不是一个好的(甚至可行的)解决方案 - 我只是删除你的语法问题 - 为了得到一个好的解决方案,你应该首先处理你的{{1 (表现不佳 - 有更好的计算方法 - 提示:在你的搜索引擎上搜索Haskell + Fib)
以下是一些评论:
zip3
部分相同列表的3倍 - 你可以让你的funct
做这项工作(顺便说一下:你已经做了 - 你忽略第二和第三参数)dropWhile
然后抬头? (filter
和头部似乎更自然IMO)funct
部分(注意你从不需要元组中的中间项?)祝其他运动好运;)
我清理了你的解决方案:
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
仍然没有更好的表现(这是你的挑战),但至少它适用于3
数字而不是1000
(尽管即使10
也会这需要相当长的时间......)
<强>享受强>
我必须尝试它,确实如果你定义这样的序列:
import Data.List (unfoldr)
fibs :: [Integer]
fibs = unfoldr fib (1,1)
where fib (n,m) = Just (n,(m,n+m))
(这与你在循环中通常所做的相近)
你会很快得到答案(4782
)
当然你必须考虑如何获取索引(提示:现在zip
可能是一个好主意)