haskell中的euler问题3项目
我是Haskell的新手,试着从中解决3个问题 我的解决方案:haskell中的euler问题3项目,haskell,project,Haskell,Project,我是Haskell的新手,试着从中解决3个问题 我的解决方案: import Data.List getD :: Int -> Int getD x = -- find deviders let deriveList = filter (\y -> (x `mod` y) == 0) [1 .. x] filteredList = filter isSimpleNumber deriveList in maximum filteredList -- Ch
import Data.List
getD :: Int -> Int
getD x =
-- find deviders
let deriveList = filter (\y -> (x `mod` y) == 0) [1 .. x]
filteredList = filter isSimpleNumber deriveList
in maximum filteredList
-- Check is nmber simple
isSimpleNumber :: Int -> Bool
isSimpleNumber x = let deriveList = map (\y -> (x `mod` y)) [1 .. x]
filterLength = length ( filter (\z -> z == 0) deriveList)
in
case filterLength of
2 -> True
_ -> False
我尝试跑步,例如:
getD 13195
> 29
但当我尝试时:
getD 600851475143
我收到错误异常:Prelude.maximum:空列表为什么
谢谢你@Barry Brown,我想我必须使用:
getD :: Integer -> Integer
但我得到了一个错误:
Couldn't match expected type `Int' with actual type `Integer'
Expected type: [Int]
Actual type: [Integer]
In the second argument of `filter', namely `deriveList'
In the expression: filter isSimpleNumber deriveList
谢谢。您的类型签名将整数值限制在2^29左右。尝试将
Int
更改为Integer
编辑:
我发现您已经意识到需要使用Integer而不是Int。您需要同时更改getD和isSimpleNumber的类型,否则将导致类型不匹配
同样,如果您在类型方面遇到问题,只需删除类型声明,让Haskell告诉您正确的类型
Main> :t getD
getD :: Integral a => a -> a
Main> :t isSimpleNumber
isSimpleNumber :: Integral a => a -> Bool
在您发现错误后,我可以指出您的解决方案非常冗长吗?在这种情况下,使用蛮力的非常简单的实现就足够了:
getD n = getD' n 2 where
getD' n f | n == f = f
| n `mod` f == 0 = getD' (n `div` f) f
| otherwise = getD' n (succ f)
这个问题对于蛮力解决方案来说足够简单,但这样做是个坏主意,因为project euler的整个想法都是您需要真正思考才能解决的问题(请参见答案末尾) 以下是您的程序的一些缺陷: 首先,使用rem而不是mod。效率更高 一些数学思考应该告诉您,您不需要检查isprime函数和getD函数中从1到x的所有数字,但是检查从平方根到1(或反转)的所有数字就足够了。请注意,在getD中,实际上需要过滤x和平方根之间的数字,因为要搜索最大的数字 为什么在getD中使用maximum函数?你知道这个列表是单调增长的,所以你最好得到最后一个 尽管您只需要最大的除数(即素数),但您可以从小到大计算除数列表,让计算机检查每个值是否为除数,尽管一旦找到较大的除数,就会丢弃结果。它应该通过从x到1过滤数字列表而不是从1到x来修复。这将导致计算机检查可能的最大除数的可除数(我应该怎么说?),而不是将以前检查的知识扔进垃圾箱。请注意,此优化仅在优化上一点时生效,因为否则计算机将计算所有除数 在前面的点混合的情况下,您应该过滤所有数字[x,x-1..squareroot x]并取第一个 您没有使用有效的iPrime函数。如果我是你,我会搜索isprime库函数,它保证是高效的。 还有更多
使用这种代码,您将永远无法解决更难的project euler问题。它们被设计为需要额外考虑问题(例如,注意不必从平方根开始检查更大的数字),并编写快速高效的代码。这是欧拉项目的目的;在编程方面要聪明。所以不要跳过它。哪种版本的Haskell?也就是说,您使用的是哪种环境?有些不支持任意精度整数。任意精度整数实际上是Haskell语言的一部分,所以这不是真的。没有忽略它们的Haskell实现。“如果您在类型方面遇到问题,只需删除类型声明并让Haskell告诉您正确的类型”——这对于Haskell新手来说是一个非常糟糕的建议。我认为在学习哈斯克尔时,最好是手写所有的字体。为了更好地理解类型系统。你自己算出类型是很理想的,但这不是OP在这里所做的。让GHC告诉你这种类型比让StackOverflow上的人告诉你更有教育意义。我目前正在尝试这个问题,并且正在这样做。。。但它似乎不起作用。你知道为什么吗?main=do-let-pgen(p:xs)=p:pgen[x | x 0]print(最后一次([x | x我用它来表示“factor”)。我自己倾向于使用函数
fn
,但我同意d
会更好。
getD n = getD' n 2 where
getD' n f | n == f = f
| n `mod` f == 0 = getD' (n `div` f) f
| otherwise = getD' n (succ f)