module Exercise_12 where import Data.List (nub, elemIndex, union, delete) import Data.Maybe (fromJust, isJust) 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-} -- Two pretty straightforward implementations. encrypt :: String -> String encrypt s = (map ((s!!) . subtract 1) $ primes $ length s) ++ (map snd . filter (not . isPrime . fst) $ zip [1..] s) decrypt :: String -> String -- I noticed both the primal and non-primal indices need the number of primes smaller or equal to the respective index. -- So I factored that out, saving one token; at the price of great unreadability. decrypt s = [s !! ((if isPrime i then fromJust . elemIndex i else (subtract . subtract (i - 1) $ length $ primes i) . length) $ primes $ length s) | i <- [1..length s]] {-TTEW-}