Advertisement
Guest User

Untitled

a guest
Apr 3rd, 2014
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 2.27 KB | None | 0 0
  1. type CodeTree =
  2.     | Branch of CodeTree * CodeTree * list<char> * int
  3.     | Leaf of char * int
  4.  
  5. let chars tree =
  6.     match tree with
  7.         | Branch(_,_,chars,_) -> chars
  8.         | Leaf(char,_) -> [ char ]
  9.  
  10. let weight tree =
  11.     match tree with
  12.         | Branch(_,_,_, weight)
  13.         | Leaf(_, weight) -> weight
  14.  
  15. let createCodeTree text =
  16.     let rec combineTrees trees =
  17.        
  18.         let makeCodeTree l r =
  19.             Branch(l,r, chars l @ chars r, weight l + weight r)
  20.         match trees with
  21.             | fst :: snd :: rest -> combineTrees (makeCodeTree fst snd :: rest |> List.sortBy weight)
  22.             | _ -> trees
  23.     let orderedLeafList =
  24.         text
  25.             |> Seq.countBy id
  26.             |> Seq.sortBy snd
  27.             |> Seq.map (fun f -> Leaf(fst f, snd f))
  28.             |> List.ofSeq
  29.     orderedLeafList
  30.         |> combineTrees
  31.         |> List.head
  32.  
  33. let decode tree bits =
  34.     let rec doDecode _tree bits chars =
  35.         match _tree with
  36.             | Branch(l, r, _, _)  ->
  37.                 match bits |> List.head with
  38.                     | 0 -> doDecode l bits.Tail chars
  39.                     | 1 -> doDecode r bits.Tail chars
  40.                     | _ -> raise (ArgumentOutOfRangeException "Invalid bit in bits")
  41.             | Leaf(c, _) when bits.IsEmpty -> c :: chars
  42.             | Leaf(c, _) -> doDecode tree bits (c :: chars)
  43.     doDecode tree bits [] |> List.rev
  44.  
  45. let encode tree text =
  46.     let hasCharInBranch tree c =
  47.       match tree with
  48.         | Branch(_, _, cs, _) -> cs |> List.exists (fun _c -> _c = c)
  49.         | Leaf(char, _) -> char = c
  50.  
  51.     let rec doEncode _tree (chars : list<char>) bits =
  52.       if chars.IsEmpty then bits
  53.       else
  54.         match _tree with
  55.           | Branch(left, right, _, _) ->
  56.             if hasCharInBranch left chars.Head then
  57.               doEncode left chars (0 :: bits)
  58.             else
  59.               doEncode right chars (1 :: bits)
  60.           | Leaf(c, _) -> doEncode tree chars.Tail bits
  61.  
  62.     doEncode tree text [] |> List.rev
  63.  
  64. let fastEncode tree =
  65.     let codeMap = chars tree
  66.                         |> Seq.map (fun c -> (c, encode tree [c]))
  67.                         |> Map.ofSeq
  68.     fun text -> List.foldBack (fun c s -> Map.find c codeMap @ s) (text |> List.ofSeq) []
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement