【问题标题】:Fermat Primality Test Haskell费马素性检验 Haskell
【发布时间】:2017-12-05 16:33:04
【问题描述】:

我已经实现了以下两个函数来确定 n 是否为 fermat 素数(如果为真则返回 n,否则返回 -1),但它始终返回 -1,不知道为什么(gc 是函数taht计算gcd)

fermatPT :: Int -> Int
fermatPT n = fermatPT' n list
  where
    list = [a | a <- [1..n-1]]

-- | heper function
fermatPT' :: Int -> [Int] -> Int
fermatPT' n l      | gc (n, head l) == 1 && fermatTest n (head l) = fermatPT' n (tail l)
                   | null l                                       = n
                   | otherwise                                    = -1
                where
                  fermatTest n a = mod (a^(n-1)) n == 1

【问题讨论】:

  • 为什么不TrueFalse?我真的不明白为什么你把东西编码为Ints,如果这些是真值
  • 或者如果您需要返回数字,只需 n 和 Nothing
  • list 有点毫无意义;你可以写fermatPT n = fermatPT' n [1..n-1]
  • 如果它总是返回 -1,那么gc 可能有问题导致它永远不会返回 1。

标签: haskell math primality-test


【解决方案1】:

您的函数应返回一个布尔值,指示给定数字是否为素数。如果你这样做,你可以使用all 函数将其简单地定义为

fermatPT :: Integer -> Bool
fermatPT n = all (fermatTest n) (filter (\a -> gcd n a == 1) [1..n-1])
             where fermatTest n a = mod (a^(n-1)) n == 1

gcd 在 Prelude 中定义。

all 避免了要求您一次将测试应用于[1..n-1] 的一个元素的显式递归;它的定义是有效的

all _ [] = True
all p (x:xs) = p x && all p xs

请注意,mod (a ^ (n - 1)) n 效率低下,因为它可能需要计算一个非常大的数字,然后才能最终将其缩小到[0..n-1] 的范围内。相反,利用ab mod n == (a mod n * b mod n) mod n 的事实,并在每次乘法后减少值。一种实现方式(不是最快的,但很简单):

modN :: Integer -> Integer -> Integer -> Integer
modN a 0 _ = 1
modN a b n = ((a `mod` n) * (modN a (b - 1) n)) `mod` n

然后使用

fermatTest n a = modN a (n-1) n == 1

请注意,您可以使用它(使用Int 而不是Integer)来正确实现fermatPT :: Int -&gt; Bool;尽管输入仍将被限制为较小的整数,但它不会出现溢出。

【讨论】:

  • 我知道它应该返回一个布尔值,但练习的第二部分是如果 n 不是素数,则返回较低的费马见证。
  • 不幸的是,这个解决方案仍然不起作用,fermatPT 53 返回 false,应该返回 True
  • a^(n-1) mod n 的幼稚计算遇到了溢出错误;将类型签名更改为 Integer -&gt; Bool 似乎可以解决它。 (例如,52 ^ 52 :: Int == 0,而52 ^ 52 :: Integer == 170676555274132171974277914691501574771358362295975962674353045737940041855191232907575296)。
猜你喜欢
  • 2013-03-03
  • 1970-01-01
  • 2013-10-16
  • 1970-01-01
  • 2011-04-30
  • 1970-01-01
  • 2021-02-18
  • 1970-01-01
  • 2020-09-25
相关资源
最近更新 更多