【问题标题】:Circular prime numbers圆形素数
【发布时间】:2019-10-01 09:23:07
【问题描述】:

我正在尝试将以下测试数字是否为素数的函数转换为另一个测试整数是否为循环素数的函数。 例如。 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

【问题讨论】:

  • 你尝试旋转数字是什么?
  • 我不知道如何旋转数字以将数字如 1193 转换为 1931,9311,3119
  • 您能否做出公平的尝试来实现它并指定该尝试不起作用的地方?提示:使用stackoverflow.com/questions/3963269/…

标签: haskell integer primes


【解决方案1】:

您可以通过以下方式轻松地提高 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 作为练习。

【讨论】:

  • 您能否提供更简单的方法,因为这里有很多我不明白的地方。如果您可以使用重复问题中的功能提出解决方案,我将不胜感激
【解决方案2】:

参考您的问题here,您可以通过添加一个新功能来实现您想要的:

check :: Integer -> Bool
check n = and [isPrime (stringToInt cs) | cs <- circle (intToString n)]

这是为了从您已经在特定代码中的位置添加一个更易于理解的解决方案,因为我可以看到您专门要求这样做。用法:

*Main> check 1931
True

*Main> check 1019
False

请注意,我已经进行了一些类型更改。我假设您希望每个函数都是特定于类型的,因为它们的名称。完整代码,取自您的示例:

circle :: String -> [String]
circle xs = take (length xs) (iterate (\(y:ys) -> ys ++ [y]) xs)

stringToInt :: String -> Integer
stringToInt x = read (x) :: Integer

intToString :: Integer -> String
intToString x = show x

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

check :: Integer -> Bool
check n = and [isPrime (stringToInt cs) | cs <- circle (intToString n)]

【讨论】:

    猜你喜欢
    • 2016-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    • 2015-11-11
    • 1970-01-01
    相关资源
    最近更新 更多