RosettaCodeData/Task/Huffman-coding/Haskell/huffman-coding-1.hs

41 lines
965 B
Haskell
Raw Permalink Normal View History

2019-09-12 10:33:56 -07:00
import Data.List (group, insertBy, sort, sortBy)
import Control.Arrow ((&&&), second)
import Data.Ord (comparing)
2013-04-10 21:29:02 -07:00
2017-09-23 10:01:46 +02:00
data HTree a
= Leaf a
| Branch (HTree a)
(HTree a)
deriving (Show, Eq, Ord)
2013-04-10 21:29:02 -07:00
test :: String -> IO ()
2017-09-23 10:01:46 +02:00
test =
2019-09-12 10:33:56 -07:00
mapM_ (\(a, b) -> putStrLn ('\'' : a : ("' : " ++ b))) .
2017-09-23 10:01:46 +02:00
serialize . huffmanTree . freq
2013-04-10 21:29:02 -07:00
serialize :: HTree a -> [(a, String)]
2017-09-23 10:01:46 +02:00
serialize (Branch l r) =
(second ('0' :) <$> serialize l) ++ (second ('1' :) <$> serialize r)
serialize (Leaf x) = [(x, "")]
2013-04-10 21:29:02 -07:00
2017-09-23 10:01:46 +02:00
huffmanTree
:: (Ord w, Num w)
=> [(w, a)] -> HTree a
huffmanTree =
snd .
2019-09-12 10:33:56 -07:00
head . until (null . tail) hstep . sortBy (comparing fst) . fmap (second Leaf)
2013-04-10 21:29:02 -07:00
2017-09-23 10:01:46 +02:00
hstep
:: (Ord a, Num a)
=> [(a, HTree b)] -> [(a, HTree b)]
hstep ((w1, t1):(w2, t2):wts) =
insertBy (comparing fst) (w1 + w2, Branch t1 t2) wts
2013-04-10 21:29:02 -07:00
2017-09-23 10:01:46 +02:00
freq
:: Ord a
=> [a] -> [(Int, a)]
2019-09-12 10:33:56 -07:00
freq = fmap (length &&& head) . group . sort
main :: IO ()
main = test "this is an example for huffman encoding"