DEV Community staff staff

Posted on

Daily Challenge #127 - Playing with Passphrases

Everyone has to use passwords. One can choose a password from poems, songs, movies names and so on. Unfortunately, some passwords can be easily guessed from lists of common cultural references. You can make your passwords stronger through different means, such as writing a function to do the following:

Select some text in capital letters, optionally including digits and non alphabetic characters,
Shift each letter by a given number but the transformed letter must be a letter (circular shift),
Replace each digit by its complement to 9,
Keep such as non alphabetic and non digit characters,
Lowercase each letter in odd position, uppercase each letter in even position (the first character is in position 0),
reverse the whole result.


your text: "BORN IN 2015!", shift 1

1 + 2 + 3 -> "CPSO JO 7984!"

4 "CpSo jO 7984!"

5 "!4897 Oj oSpC"

With longer passwords, isn't it better to have a small and easy program? How would you write it?

This challenge comes from g964 on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email with your suggestions!

Top comments (1)

jvanbruegge profile image
Jan van Brügge • Edited

Haskell solution, will happily answer questions:

import Data.Maybe (fromMaybe)
import Data.List (elemIndex)
import Data.Char (digitToInt, intToDigit, toUpper, toLower)

solve :: Int -> String -> String
solve n = reverse . fmapEvenOdd toUpper toLower . fmap (complement . shift n)

fmapEvenOdd :: (a -> b) -> (a -> b) -> [a] -> [b]
fmapEvenOdd f g (x:y:xs) = f x:g y:fmapEvenOdd f g xs
fmapEvenOdd f _ [x] = [f x]
fmapEvenOdd _ _ [] = []

complement :: Char -> Char
complement c
    | isDigit c = intToDigit $ 9 - (digitToInt c)
    | otherwise = c

shift :: Int -> Char -> Char
shift n c = fromMaybe c $ fmap ((chars !!) . (`mod` length chars) . (+n)) $ elemIndex c chars
    where chars = ['A'..'Z']