32 lines
1012 B
Haskell
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)
|