项目Euler - 这个haskell代码如此之快?

时间:2014-02-19 00:19:43

标签: python haskell python-3.x

我正在研究项目euler中的问题401,我在python中编写了我的解决方案但是它需要几天才能运行,显然我需要加速它或使用不同的方法。我在Haskell中遇到了一个与我的python解决方案几乎相同的解决方案,但几乎是瞬间完成的。

有人可以解释它是如此之快吗? (我没有要求提供帮助或解决问题401

divisors n = filter (\x -> n `mod` x == 0) [1..(n`div`2)] ++ [n]
sigma2 n = sum $ map (\x -> x * x) (divisors n)
sigma2big n = sum $ map (sigma2)[1..n]
let s2b = sigma2big 10^15
putStrLn ("SIGMA2(10^15) mod 10^9 is " ++ (show (mod s2b 10^9)))

根据我的理解,它只是使用试验除法生成一个除数列表,对它们进行平方和求和,然后将结果从1加到n。

编辑:忘了我的python代码

from time import clock


def timer(function):

    def wrapper(*args, **kwargs):
        start = clock()
        print(function(*args, **kwargs))
        runtime = clock() - start
        print("Runtime: %f seconds." % runtime)

    return wrapper


@timer
def find_answer():
    return big_sigma2(10**15) % 10**9

def get_divisors(n):
    divs = set()
    for i in range(1, int(sqrt(n)) + 1):
        if n % i == 0:
            divs.add(i)
            divs.add(n // i)
    return divs

def sigma2(n):
    return sum(map(lambda x: x**2, get_divisors(n)))

def big_sigma2(n):
    total = 0
    for i in range(1, n + 1):
        total += sigma2(i)
    return total

if __name__ == "__main__":
    find_answer()

2 个答案:

答案 0 :(得分:44)

Prelude> sigma2big 1000
401382971
(0.48 secs, 28491864 bytes)

Prelude> sigma2big 10^3
103161709
(0.02 secs, 1035252 bytes)

Prelude> (sigma2big 10)^3
103161709

功能优先(shh ...)

答案 1 :(得分:2)

请确保您使用Integer进行计算,而不是Int,因为10^15会溢出Int值。

如果你改变:

let s2b = sigma2big 10^15

为:

let s2b = sigma2big (10^15 :: Integer)

Haskell代码耗尽了ghci中的内存,在运行编译版本时我并没有等到它完成。