module Exercise_12 where import Data.Bifoldable (biconcat) import Data.List ( (\\) , concat , find , intersect , nub , partition , permutations , sortOn , union ) import Data.Maybe (fromJust) import Data.Ord (comparing) {-H12-} 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] {-MCCOMMENT Hello dear MC! I have another, shorter solution, that does not pass the test, as it is O(2^n). If you happen to only test very short strings while running the tests for the competition, here is my brute-force solution: decrypt :: String -> String decrypt s = fromJust . find ((== s) . encrypt) $ permutations s -} {-WETT-} encrypt :: String -> String encrypt = map snd . biconcat . partition (isPrime . fst) . zip [1 ..] decrypt :: String -> String decrypt s = map fst . sortOn snd . zip s $ primes (length s) `union` enumFrom 1 {-TTEW-}