【发布时间】:2013-05-14 20:53:56
【问题描述】:
我必须编写一个函数,它返回所有对 (x,y) 的列表,其中 x, y ∈ N , and:
- x 是两个自然数的乘积 (x = a • b, 其中 a, b ∈ N) 和
- x 确实大于 5 但确实小于 500,和
- y 是一个平方数(y = c² 其中 c ∈ N)不大于 1000,and
- x 是 y 的除数。
我的尝试:
listPairs :: [(Int, Int)]
listPairs = [(a*b, y) | y <- [0..], a <- [0..], b <- [0..],
(a*b) > 5, (a*b) < 500, (y*y) < 1001,
mod y (a*b) == 0]
但它不返回任何东西,并且计算机在它上面工作了很多。
但是,如果我为 a、b 和 y 选择较小的范围,则 e。 G。 [0..400],最多需要一分钟,但它会返回正确的结果。
那么我该如何解决性能问题呢?
【问题讨论】:
-
-1 您已经从 Haskell 咖啡馆获得了大量帮助,请不要从一个站点到另一个站点寻求帮助(Danny Gratzer)
-
对于那些不知道我在说什么的人来说,这是由 OP 提出的,今天下午已经详细回答了 (groups.google.com/forum/?fromgroups=#!topic/haskell-cafe/…)
-
400太低。你应该确保你没有错过任何正确的解决方案:(a*b)<500, (a*b)>5, a==1, b==499是一致的。所以使用[1..499](0*x > 5永远不会是真的)。 OTOH(y*y) < 1001==>y < 32所以使用y<-[1..31], a<-[1..499]。应该让它快 32 倍。然后,a*b < 500和a*b==b*a所以使用b<-[a..min 499 (div 500 a)]这让我们的问题规模又大大减少了。现在只需不到一秒钟。 -
顺便说一句,根据您的描述,您应该返回
[(a*b, y*y) | ...。y您的代码是您描述的“c”。 -
指定的重复项回答了不同的问题。这个问题是具体的,一个是一般性的。
标签: performance list haskell list-comprehension