【发布时间】:2016-05-28 07:45:05
【问题描述】:
这是一个来自 SPOJ 的简单编程问题:http://www.spoj.com/problems/PROBTRES/。
基本上,您被要求为 i 和 j 之间的数字输出最大的 Collatz 循环。 (数字 $n$ 的 Collatz 循环是最终从 $n$ 到 1 的步数。)
我一直在寻找一种 Haskell 方法来解决与 Java 或 C++ 相比性能比较的问题(以适应允许的运行时限制)。尽管一个简单的 Java 解决方案可以记住任何已计算的周期的周期长度。我没有成功地应用这个想法来获得 Haskell 解决方案。
我已经尝试了 Data.Function.Memoize,以及使用这篇文章中的想法的自制日志时间记忆技术:Memoization in Haskell?。不幸的是,记忆化实际上使 cycle(n) 的计算更慢。我相信减速来自haskell方式的开销。 (我尝试使用编译后的二进制代码运行,而不是解释。)
我还怀疑,简单地将数字从 i 迭代到 j 可能代价高昂 ($i,j\le10^6$)。所以我什至尝试使用来自http://blog.openendings.net/2013/10/range-trees-and-profiling-in-haskell.html 的想法预先计算范围查询的所有内容。但是,这仍然会出现“超出时间限制”错误。
您能否为此提供一个整洁的、有竞争力的 Haskell 程序?
谢谢!
【问题讨论】:
-
这不是和Project Euler 14本质上一样吗?在这种情况下,您可能对in one of my older answers 感兴趣。
-
这个问题是我写
data-memocombinators的原因。如果你只记住低于阈值的输入的循环长度函数(例如使用arrayRange),它会很好地工作。 -
也许分享您的代码将使我们能够更有效地帮助您。
标签: haskell functional-programming