带索引的Sigma表示法

时间:2014-10-13 13:27:26

标签: haskell algebra generalization

我一直在尝试解决一个需要Sigma Notation的问题(或者至少我认为),但是我遇到的Haskell中Sigma Notation的每个实现都没有在其函数中使用索引变量。我一直试图复制的特定公式是:

enter image description here

它用于计算n!中的尾随零的数量,但我得到的最好的是:

 sigma :: (Enum a, Num b) => a -> a -> (a -> b) -> b
 sigma i k fn = sum . map fn $ [i..k]

 zeros :: Int -> Int
 zeros n = sigma 1 n (???)

我正在尝试创建一个通用的sigma函数,它与f中的索引变量一起使用。 这有效,但对于100 !,它给出-11尾随零。溢出?

zeros :: Int -> Int
zeros n = sigma 1 n (\i -> n `div` 5 ^ i)
        where sigma i k fn = sum $ map fn [i..k]

P.S。我在浏览器中限制编译时间的IDE。 (所以速度很重要)

2 个答案:

答案 0 :(得分:2)

你的麻烦只来自类型不匹配。您希望在最后执行truncate并使用小数运算进行除法,取幂和求和,然后在结尾处截断结果。因此,您需要的不仅仅是zeros n = sigma 1 n something

zeros :: Integral a => a -> a
zeros n = truncate $ sigma 1 n (\i -> fromIntegral n / 5 ^ i)

您需要担心的详细信息是fromIntegral n,它将nIntegral a => a转换为Num b => b^运算符允许{ {1}}参数作为指数,因此我们不需要在那里进行转换,然后Integral a => a将转换回truncate。我们可以使这个签名更加通用,并返回我们输入的不同Integral,但这在实践中并没有用。

现在我们可以输入IntegralInt,具体取决于您需要输入此函数的数量的大小(因为您提到了Integer),但请注意制作100!元素列表会严重占用RAM和CPU时间。

如果你真的想要计算大数的尾随零,那么将它转换为字符串可能要容易得多,如:

100!

答案 1 :(得分:1)

sigma i k fn = sum $ map fn [i..k]
zeros n = sigma 1 n (\i -> fromIntegral n / 5**(fromIntegral i))

Haskell不会自动在整数和浮点数之间进行转换。这就是您需要fromIntegral

的原因