import Control.Arrow
import Data.List
import Test.QuickCheck
import Data.Char
instance Arbitrary Char where
arbitrary = choose ('\0', '\255')
coarbitrary c = variant (ord c `rem` 4)
compress :: String -> String
compress xs = group xs >>= (head &&& length >>> encode)
where encode (c, n) | c == '~' = concat . replicate n $ "~A~"
| n < 4 = replicate n c
| n > 26 = encode (c, 26) ++ encode (c, n-26)
| otherwise = '~' : toEnum (fromEnum 'A' + n - 1 ) : [c]
expand :: String -> String
expand [] = []
expand ('~':n:c:cs) = replicate (fromEnum n - fromEnum 'A' + 1) c ++ expand cs
expand (c:cs) = c : expand cs
main = quickCheck prop_expandcompress >>= print
prop_expandcompress x = (expand . compress) x == id x
where _ = x :: String