我刚刚开始学习一些Haskell和函数编程,但我发现很难掌握它:)
我正在尝试将一小段ruby代码翻译成Haskell(因为我喜欢概念函数编程和Haskell提出的甚至更多因为我来自数学领域而Haskell似乎非常数学化):
class Integer
def factorial
f = 1; for i in 1..self; f *= i; end; f
end
end
boundary = 1000
m = 0
# Brown Numbers - pair of integers (m,n) where n factorial is equal with square root of m
while m <= boundary
n = 0
while n <= boundary
puts "(#{m},#{n})" if ((n.factorial + 1) == (m ** 2))
n += 1
end
m += 1
end
我只能弄清楚如何做阶乘:
let factorial n = product [1..n]
我无法弄清楚如何在Haskell中执行while循环或等效操作,即使我发现了一些让我感到困惑的例子。
这个想法是循环从0
(或1
)开始并继续(增量为1),直到它到达边界(在我的代码中为1000
)。存在边界的原因是因为我正在考虑启动执行相同操作的并行任务但是在不同的时间间隔,因此我期望的结果返回得更快(一个操作将在1
上完成{{1} },另一个10000
到10000
等。)
如果有人能帮忙解决这个问题,我将非常感激:)
答案 0 :(得分:8)
试试这个:
let results = [(x,y) | x <- [1..1000], y <- [1..1000] ,1 + fac x == y*y]
where fac n = product [1..n]
这是列表理解。更多关于here。
将其映射到您的Ruby代码,
m
和n
中的嵌套循环已替换为x
和y
。基本上,在指定范围内对x
和y
的值进行迭代(在本例中为1到1000)。where
允许我们创建辅助函数来计算阶乘。请注意,我们可以在适当的位置计算阶乘,而不是单独的函数,如下所示:
(1 + product[1..x]) == y * y
最终,左侧的(x,y)
表示它返回一个元组(x,y)
列表,这些是您的布朗数字。
好的,这应该适用于你的.hs文件:
results :: [(Integer, Integer)] --Use instead of `Int` to fix overflow issue
results = [(x,y) | x <- [1..1000], y <- [1..1000] , fac x == y*y]
where fac n = product [1..n]
答案 1 :(得分:0)
要添加到shree.pat18的答案,也许您可以尝试的练习是将Haskell解决方案转换回Ruby。它应该是可能的,因为Ruby的范围是Enumerator::Lazy
和Enumerable#flat_map
。以下重写的Haskell解决方案应该有所帮助:
import Data.List (concatMap)
results :: [(Integer, Integer)]
results = concatMap (\x -> concatMap (\y -> test x y) [1..1000]) [1..1000]
where test x y = if fac x == y*y then [(x,y)] else []
fac n = product [1..n]
请注意,Haskell concatMap
或多或少与Ruby Enumerable#flat_map
相同。