added unary encoding

This commit is contained in:
Stefan Friese 2024-11-19 18:24:36 +01:00
parent e39ac84573
commit 85b57ef9aa
2 changed files with 64 additions and 0 deletions

View File

@ -31,6 +31,7 @@
module Encoding.Base2
( enc2
, dec2
, binaryToChar
) where
import Data.Char (ord, chr, digitToInt, intToDigit)

63
src/Encoding/Unary.hs Normal file
View File

@ -0,0 +1,63 @@
module Encoding.Unary
( encunary
, decunary
) where
import Data.ByteString (ByteString)
import Data.List (group)
import qualified Data.ByteString.Char8 as BC
import Encoding.Base2 (dec2, enc2, binaryToChar)
import Debug.Trace (trace)
encodeChuckNorris :: ByteString -> ByteString
encodeChuckNorris binary =
let cleanBinary = BC.filter (/= ' ') binary
in BC.unwords . concatMap encodeRunLength . group $ BC.unpack cleanBinary
where
encodeRunLength :: String -> [ByteString]
encodeRunLength xs@(x:_) = [prefix x, BC.pack (replicate (length xs) '0')]
encodeRunLength [] = []
prefix '0' = BC.pack "00"
prefix '1' = BC.pack "0"
prefix c = error $ "Invalid binary character encoding" ++ show c
pairs :: [a] -> [(a, a)]
pairs (x:y:rest) = (x, y) : pairs rest
pairs _ = []
encunary :: ByteString -> ByteString
encunary input = encodeChuckNorris $ enc2 input
decodeChuckNorris :: ByteString -> ByteString
decodeChuckNorris encoded = BC.pack . concatMap (BC.unpack . decodeRunLength) . pairs . BC.words $ encoded
where
decodeRunLength :: (ByteString, ByteString) -> ByteString
decodeRunLength (prefix, zeros)
| prefix == BC.pack "00" = BC.replicate (BC.length zeros) '0'
| prefix == BC.pack "0" = BC.replicate (BC.length zeros) '1'
| otherwise = error "Invalid Unary encoding"
-- pairs (x:y:rest) = (x, y) : pairs rest
-- pairs _ = []
-- decodeRunLength ("00", zeros) = replicate (BC.length zeros) '0'
-- decodeRunLength ("0", zeros) = replicate (BC.length zeros) '1'
-- decodeRunLength _ = error "Invalid Unary encoding"
decunary :: ByteString -> ByteString
decunary encoded =
let binaryStr = decodeChuckNorris encoded
in BC.pack $ map binaryToChar (chunkBinaryString binaryStr)
where
chunkBinaryString :: ByteString -> [ByteString]
chunkBinaryString bs
| BC.null bs = []
| otherwise = let (chunk, rest) = BC.splitAt 8 bs
in chunk : chunkBinaryString rest
-- encunary input =
-- let binaryStr = enc2 input
-- in trace (show binaryStr) $ encodeChuckNorris binaryStr
-- decunary :: ByteString -> ByteString
-- decunary encoded = dec2 $ decodeChuckNorris encoded