RosettaCodeData/Task/Unprimeable-numbers/Haskell/unprimeable-numbers.hs

32 lines
1012 B
Haskell

import Control.Lens ((.~), ix, (&))
import Data.Numbers.Primes (isPrime)
import Data.List (find, intercalate)
import Data.Char (intToDigit)
import Data.Maybe (mapMaybe)
import Data.List.Split (chunksOf)
import Text.Printf (printf)
isUnprimable :: Int -> Bool
isUnprimable = all (not . isPrime) . swapdigits
swapdigits :: Int -> [Int]
swapdigits n = map read $ go $ pred $ length digits
where
digits = show n
go (-1) = []
go n'' = map (\x -> digits & (ix n'') .~ intToDigit x) [0..9] <> go (pred n'')
unPrimeable :: [Int]
unPrimeable = filter isUnprimable [1..]
main :: IO ()
main = do
printf "First 35 unprimeable numbers:\n%s\n\n" $ show $ take 35 unPrimeable
printf "600th unprimeable number: %d\n\n" $ unPrimeable !! 599
mapM_ (uncurry (printf "Lowest unprimeable number ending with %d: %10s\n")) $ mapMaybe lowest [0..9]
where
thousands = reverse . intercalate "," . chunksOf 3 . reverse
lowest n = do
x <- find (\x -> x `mod` 10 == n) unPrimeable
pure (n, thousands $ show x)