Круглые простые числа - PullRequest
       28

Круглые простые числа

1 голос
/ 01 октября 2019

Я пытаюсь преобразовать следующую функцию, которая проверяет число, если оно является простым, в другую, которая проверяет, является ли целое число круглым простым числом. например. 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

Ответы [ 2 ]

1 голос
/ 01 октября 2019

Вы можете легко повысить эффективность и элегантность своей функции 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 для этих чисел в качестве упражнения.

0 голосов
/ 04 октября 2019

Ссылка на ваш вопрос здесь , вы можете достичь желаемого, добавив одну новую функцию:

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)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...