首页 > 解决方案 > 圆形素数

问题描述

我正在尝试将以下测试数字是否为素数的函数转换为另一个测试整数是否为循环素数的函数。例如。1193 是圆素数,因为 1931、9311 和 3119 也是素数。所以我需要旋转整数的数字并测试该数字是否为素数。有任何想法吗?注意:我是 Haskell 编程的新手

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 


isCircPrime ::  Integer -> Bool

标签: haskellintegerprimes

解决方案


您可以通过将isPrime其实现为:

isPrime ::  Integral i => i -> Bool
isPrime 1 = False
isPrime n = all ((/=) 0 . mod n) (takeWhile (\x -> x*x <= n) [2..])

为了旋转数字,我们可以在这里使用两个辅助函数:一个将数字转换为数字列表,另一个将数字列表转换为数字,我们反过来做,因为这样更方便实施,但没关系:

num2dig :: Integral i => i -> [i]
num2dig n | n < 10 = [n]
          | otherwise = r : num2dig q
    where (q, r) = quotRem n 10


dig2num :: (Foldable t, Num a) => t a -> a
dig2num = foldr ((. (10 *)) . (+)) 0

现在我们可以创建一个简单的函数来为项目列表生成所有旋转:

import Control.Applicative(liftA2)
import Data.List(inits, tails)

rots :: [a] -> [[a]]
rots = drop 1 . liftA2 (zipWith (++)) tails inits

所以我们可以用它来构造所有旋转的数字:

rotnum :: Integral i => i -> [i]
rotnum = map dig2num . rots . num2dig

例如对于1425,旋转的数字是:

Prelude Control.Applicative Data.List> rotnum 1425
[5142,2514,4251,1425]

我将使用isPrime这些数字作为练习。


推荐阅读