module Exercise_12 where import Data.List (nub, (\\)) import Data.Bifunctor (first, second, bimap) import Data.Tuple import Control.Monad ((>=>), ap) import Control.Applicative import Control.Arrow ((&&&)) import System.IO 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-} -- build substring from index list ŧ :: String -> [Int] -> String ŧ s=foldr((:)`fmap`s!!)[] þ :: String -> [Int] þ=map pred.primes.length encrypt :: String -> String encrypt=þ>>= \p s->s`ŧ`p++s`ŧ`(enumFromTo 0 (length s - 1)\\p) -- insert character into string by (Index, Char) list ø :: [(Int, Char)] -> String -> String ø=flip(foldl(flip(splitAt.fst)>=>(uncurry(++).).flip(second.(:).snd))) -- foldl receives String and (Int, Char), which have to flipped for pointfree variant -- (splitAt . fst) :: (Int, Char) -> String -> (String, String) -- (second . (:) . snd) :: (Int, Char) -> (String, String) -> (String, String) decrypt :: String -> String decrypt=þ>>=(uncurry ø.).(splitAt.length<**>fmap.first.zip) -- 1. get prime index list by þ -- 2. (splitAt.length<**>fmap.first.zip) receives this list and a string and returns ([(i, c)], s2) -- where i = index of c to be inserted into s2 {-TTEW-}