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