我试图在Project Euler上做一些有趣的工作,但我现在陷入了一个问题,想要继续前进,但似乎无法让我的功能正常工作。我试图计算给定整数的素因子。该功能适用于较小的数字,如13195:
> primeFactor 13195
[29,13,7,5]
但是当我运行一个更大的数字,如600851475143:
> primeFactor 601851475143
[]
这对我来说似乎很奇怪。我知道haskell是一种懒惰的语言,但我不认为它应该是懒惰的......
primeFactor' :: Int -> [Int]
primeFactor' n = [ p | p <- primes' [] [2 .. n], n `mod` p == 0 ]
where primes' :: [Int] -> [Int] -> [Int]
primes' ys [] = ys
primes' ys (x:xs) | x `notMultipleOf` ys = primes' (x:ys) xs
| otherwise = primes' ys xs
-- helper function to primeFactor'
notMultipleOf :: Int -> [Int] -> Bool
notMultipleOf n [] = True
notMultipleOf n xs = and [n `mod` x /= 0 | x <- xs]
答案 0 :(得分:2)
Int
有32位,您无法存储该数字(使用Integer
)。
另一方面,您可以使用Data.Numbers.Primes
(和see code):
> primeFactors 601851475143
[3,3,23,1009,2881561]
> primeFactors 600851475143
[71,839,1471,6857]
答案 1 :(得分:2)
这是一个整数溢出错误。 Int
类型只能代表最高2^31 - 1
>> maxBound :: Int
2147483647
您输入的号码溢出 -
>> 601851465143 :: Int
556043703
另一方面,如果您使用Integer
类型,则没有溢出 -
>> 601851465143 :: Integer
601851465143
答案 2 :(得分:1)
老实说,我不知道你为什么得到一个空名单....或者任何东西。
您正在使用强力方法查找素数列表,将所有数字除以所有较小的素数。这类似于n ^ 2。
这需要多长时间才能完成?
N^2 ~= (601851475143)^2 ~= 10^22 operations
它比这要好一点,因为素数的密度会下降,但不会太多......让我们减去10 ^ 2的因子来解释这个问题。在现代的8核4GHz机器上(假设每个操作1cpu周期....方式乐观),这应该采取
10^20 operations / (10^10 operation/sec) = 10^10 sec ~= 300 years
完成。
您可能想要寻找新算法。