fork(1) download
  1. module Main where
  2.  
  3. import Data.List (nub)
  4. import Data.Map hiding (map)
  5.  
  6. data Trie a x = Trie x (Map a (Trie a x))
  7.  
  8. lzwCompress :: Ord a => [a] -> [a] -> [Int]
  9. lzwCompress cs [] = []
  10. lzwCompress cs xs = loop (length cs) xs id (Trie (-1) d0)
  11. where
  12. d0 = fromList (zip cs (map (\n -> Trie n empty) [0..]))
  13. loop _ [] _ (Trie i _) = [i]
  14. loop n (x:xs) c (Trie i d)
  15. | member x d = loop n xs c1 (d ! x)
  16. | otherwise = i : loop (n+1) (x:xs) id (c1 (Trie n empty))
  17. where c1 = c . (\t -> Trie i (insert x t d))
  18.  
  19. lzwDecompress :: [a] -> [Int] -> [a]
  20. lzwDecompress cs is = concat xss
  21. where
  22. xss = map (d !!) is
  23. d = map (:[]) cs ++ zipWith (++) xss (map (take 1) (tail xss))
  24.  
  25. test :: [Char] -> String -> IO ()
  26. test cs xs = do
  27. putStrLn $ "characters: " ++ cs
  28. putStrLn $ "uncompressed: " ++ xs
  29. let comp = lzwCompress cs xs
  30. putStrLn $ "compressed: " ++ show comp
  31. putStrLn $ "decompressed: " ++ lzwDecompress cs comp ++ "\n"
  32.  
  33. main :: IO ()
  34. main = do
  35. test "0123" "010101010"
  36. test "0123" "01230123012"
  37. test "0123" "00001110000"
  38. let akamaki = "akamakigami aomakigami kimakigami"
  39. test "o kgami" akamaki
  40. test (nub akamaki) akamaki
Success #stdin #stdout 0s 4560KB
stdin
Standard input is empty
stdout
characters: 0123
uncompressed: 010101010
compressed: [0,1,4,6,5]
decompressed: 010101010

characters: 0123
uncompressed: 01230123012
compressed: [0,1,2,3,4,6,8]
decompressed: 01230123012

characters: 0123
uncompressed: 00001110000
compressed: [0,4,0,1,7,5,0]
decompressed: 00001110000

characters: o kgami
uncompressed: akamakigami aomakigami kimakigami
compressed: [4,2,4,5,7,6,3,9,6,1,4,0,10,2,12,14,1,20,19,21,5,6]
decompressed: akamakigami aomakigami kimakigami

characters: akmig o
uncompressed: akamakigami aomakigami kimakigami
compressed: [0,1,0,2,7,3,4,9,3,5,0,6,10,1,12,14,5,20,19,21,2,3]
decompressed: akamakigami aomakigami kimakigami