module Exercise_12 where import Data.List import Data.Monoid import Data.Function import Data.Char import Control.Arrow import Control.Monad import Control.Applicative isPrime :: Int -> Bool isPrime n | n <= 1 = False | otherwise = primeAux (n - 1) where primeAux 1 = True primeAux i = n `mod` i /= 0 && primeAux (i - 1) -- returns all primes up to the passed number primes :: Int -> [Int] primes n = [ i | i <- [2 .. n], isPrime i ] {-WETT-} encrypt :: String -> String encrypt = map snd . uncurry mappend . partition (isPrime . fst) . zip [1 ..] decrypt :: String -> String decrypt = map fst . sortOn snd <<< zip -- some magic with precedence <*> encrypt . map chr . enumFromTo 1 -- either of the enc/dec functions must be strict . length -- else this won't work {- This one apparently works, but the usage of unsafe methode is terrible -} -- import Unsafe.Coerce -- decrypt :: String -> String -- decrypt = map fst . sortOn snd <<< zip <*> encrypt . unsafeCoerce . enumFromTo 1 . length {- if the type signature could be generalized, -- this can be even shorter by remove mapping to Char -} -- encrypt :: [a] -> [a] -- encrypt = map snd . uncurry mappend . partition (isPrime . fst) . zip [1 ..] -- -- dec :: [a] -> [a] -- decrypt = map fst . sortOn snd <<< zip <*> encrypt . enumFromTo 1 . length {-TTEW-}