我是Haskell的新手并尝试从http://projecteuler.net/解决3个问题。
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
我的解决方案:
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
谢谢。
答案 0 :(得分:6)
您的类型签名将整数值限制为大约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
答案 1 :(得分:4)
发现错误后,我是否可以指出您的解决方案非常详细?在这种情况下,使用强力的非常简单的实现就足够了:
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)
答案 2 :(得分:1)
这个问题对于暴力解决方案来说很容易,但这样做是个坏主意,因为项目euler的整个想法是你需要真正想到要解决的问题(参见答案结束) 所以这里有一些程序的缺陷:
首先,使用rem而不是mod。它更有效率。
一些数学思想应该告诉你,你不需要检查isprime函数和getD函数中从1到x的所有数字,但检查从squareroot到1(或反转)的所有数字应该足够了。请注意,在getD中,您实际上需要在x和平方根之间过滤数字,因为您搜索的是最大的数字。
为什么要在getD中使用最大函数?你知道这个名单是单调增长的,所以你也可以得到最后一个。
尽管你只需要最大的除数(这是素数),你可以计算从小到大的除数列表,如果它是除数,计算机会检查每个值,尽管一旦找到更大的除数就丢弃结果。它应该通过过滤数字列表从x到1而不是从1到x来修复。这将导致计算机检查可分性(我应该怎么说?)以获得最大可能的除数,而不是将先前检查的知识扔给垃圾。请注意,此优化仅在前一个点被优化时生效,否则计算机将计算所有除数。
如果前面的点混合了,你应该过滤掉所有数字[x,x-1 .. squareroot x]并取得第一个。
您没有使用高效的isPrime功能。如果我是你,我会搜索一个isprime库函数,保证有效。 还有更多..
使用这种代码,你永远无法解决更难的项目euler问题。它们的设计需要额外考虑问题(例如,注意你不必从平方根检查更大的数字)并编写快速有效的代码。这是项目欧拉的目的;对编程很聪明。所以不要跳过它。