检查数字是否为特殊质数

时间:2019-10-10 21:13:13

标签: haskell primes

我正在尝试创建一个在Haskell中打印特殊质数的程序 isSpecialPrime :: Integer -> Bool。如果数字不是特殊质数,该函数应返回。特殊质数是可以写成两个相邻质数和1之和的质数。特殊质数的示例是19 = 7 + 11 + 1。

我设法在这里检查数字是否为质数:

isPrime ::  Integer -> Bool

isPrime 1 = False
isPrime 2 = True
isPrime n 
 | (length [x | x <- [2 .. n-1],  n  `mod` x == 0]) > 0 = False
 | otherwise = True 

任何修改代码的想法都只能返回 Special Prime

输出结果应该与此类似

> isSpecialPrime 19
True

1 个答案:

答案 0 :(得分:0)

如果使用辅助功能,则可以执行以下操作:

isPrime ::  Integer -> Bool
isPrime 1 = False
isPrime 2 = True
isPrime n 
 | (length [x | x <- [2 .. n-1],  n  `mod` x == 0]) > 0 = False
 | otherwise = True 

isSpecialPrime :: Integer -> Bool
isSpecialPrime 1 = False
isSpecialPrime x =  
 let firstNeighboring = findNeighbore x in
 isSpecialPrime' x firstNeighboring

isSpecialPrime' :: Integer -> Integer -> Bool
isSpecialPrime' _ 0 = False 
isSpecialPrime' p x =  
 let firstNeighboring = findNeighbore x in
 let secondNeighboring = findNeighbore firstNeighboring in
 if (1 + firstNeighboring + secondNeighboring) == p
 then True
 else isSpecialPrime' p firstNeighboring

findNeighbore 0 = 0
findNeighbore x = if isPrime (x-1) then x-1 else findNeighbore (x-1)

primes :: [Integer]
primes = sieve (2 : [3, 5..])
  where
    sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]

例如:

filter isSpecialPrime $ take 40 primes
=> [13,19,31,37,43,53,61,79,101,113,139,163,173]

一些优化:

isSpecialPrime' :: Integer -> Integer -> Bool
isSpecialPrime' _ 1 = False 
isSpecialPrime' p x =
 let firstNeighboring = findNeighbore x in
 let secondNeighboring = findNeighbore firstNeighboring in
 let sumNeigh = secondNeighboring + firstNeighboring in
 if (p `div` 3) > sumNeigh
  then False else 
  if (1 + sumNeigh) == p
  then True
  else isSpecialPrime' p firstNeighboring

示例:

filter isSpecialPrime $ take 100 primes
=> [13,19,31,37,43,53,61,79,101,113,139,163,173,199,211,223,241,269,277,331,353,373,397,457,463,509,521,541]