Created
February 5, 2018 00:25
-
-
Save lhcopetti/ec27f86c54cc31b3c5e9bf98817ec962 to your computer and use it in GitHub Desktop.
An example to the Vigene Cipher implementation using a monadic based solution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE RankNTypes #-} | |
{-# LANGUAGE TemplateHaskell #-} | |
module Main where | |
import Control.Monad.Trans.State | |
import Data.Char | |
import Control.Monad.Loops | |
import Control.Monad | |
import Control.Lens | |
---- Vigenere Cipher, monadic solution ----- | |
data VigenereState = VS { _text :: String | |
, _cipher :: String | |
} | |
makeLenses ''VigenereState | |
runVigenere :: String -> String -> String | |
runVigenere text cipher = evalState cipherText | |
VS { _text = text | |
, _cipher = cycle cipher | |
} | |
vigenereTransform :: Char -> Char -> Char | |
vigenereTransform l c = chr newOrd | |
where | |
initialOrd = ord 'A' | |
alphabetSize = length ['A' .. 'Z'] | |
newOrd = (ord c + ord l) `mod` alphabetSize + initialOrd | |
cipherText :: State VigenereState String | |
cipherText = whileM hasText nextCipher | |
nextCipher :: State VigenereState Char | |
nextCipher = do | |
t <- drawText | |
if isSpace t then | |
return t | |
else do | |
c <- drawCipher | |
return (vigenereTransform t c) | |
drawCipher :: State VigenereState Char | |
drawCipher = draw' cipher | |
drawText :: State VigenereState Char | |
drawText = draw' text | |
draw' :: Lens' VigenereState String -> State VigenereState Char | |
draw' f = do | |
st <- get | |
let top = head (view f st) | |
put (over f tail st) | |
return top | |
hasText :: State VigenereState Bool | |
hasText = liftM (not . null) (gets _text) | |
main = putStrLn $ runVigenere "MEET AT DAWN" "ALLY" | |
-- expected result = "MPPR AE OYWY" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment