Another update from ingydotnet^djgoku

This commit is contained in:
Ingy döt Net 2015-11-18 06:14:39 +00:00
parent 91df62d461
commit 948b86eafa
7604 changed files with 108452 additions and 22726 deletions

View file

@ -1,7 +1,7 @@
(use 'clojure.contrib.seq-utils)
(require '[clojure.pprint :refer :all])
(defn probs [items]
(let [freqs (frequencies items) sum (reduce + (vals freqs))]
(defn probs [s]
(let [freqs (frequencies s) sum (apply + (vals freqs))]
(into {} (map (fn [[k v]] [k (/ v sum)]) freqs))))
(defn init-pq [weighted-items]
@ -13,24 +13,22 @@
(defn huffman-tree [pq]
(while (> (.size pq) 1)
(let [a (.poll pq) b (.poll pq) new-node { :priority (+ (:priority a) (:priority b)), :left a, :right b }]
(let [a (.poll pq) b (.poll pq)
new-node {:priority (+ (:priority a) (:priority b)) :left a :right b}]
(.add pq new-node)))
(.poll pq))
(defn symbol-map
([t] (into {} (symbol-map t [])))
([{:keys [symbol,left,right] :as t} code]
(if symbol [[symbol code]]
(concat (symbol-map left (conj code 0))
(symbol-map right (conj code 1))))))
([t] (symbol-map t ""))
([{:keys [symbol priority left right] :as t} code]
(if symbol [{:symbol symbol :weight priority :code code}]
(concat (symbol-map left (str code \0))
(symbol-map right (str code \1))))))
(defn huffman-encode [items]
(-> items probs init-pq huffman-tree symbol-map))
(defn display-huffman-encode [s]
(println "SYMBOL\tWEIGHT\tHUFFMAN CODE")
(let [probs (probs (seq s))]
(doseq [[char code] (huffman-encode (seq s))]
(printf "%s:\t\t%s\t\t%s\n" char (probs char) (apply str code)))))
(->> s huffman-encode (sort-by :weight >) print-table))
(display-huffman-encode "this is an example for huffman encoding")

View file

@ -0,0 +1,38 @@
(require '[clojure.data.priority-map :refer [priority-map-keyfn-by]])
(require '[clojure.pprint :refer [print-table]])
(defn init-pq [s]
(let [c (count s)]
(->> s frequencies
(map (fn [[k v]] [k {:sym k :weight (/ v c)}]))
(into (priority-map-keyfn-by :weight <)))))
(defn huffman-tree [pq]
(letfn [(build-step
[pq]
(let [a (second (peek pq)) b (second (peek (pop pq)))
nn {:sym (str (:sym a) (:sym b))
:weight (+ (:weight a) (:weight b))
:left a :right b}]
(assoc (pop (pop pq)) (:sym nn) nn)))]
(->> (iterate build-step pq)
(drop-while #(> (count %) 1))
first vals first)))
(defn symbol-map [m]
(letfn [(sym-step
[{:keys [sym weight left right] :as m} code]
(cond (and left right) #(vector (trampoline sym-step left (str code \0))
(trampoline sym-step right (str code \1)))
left #(sym-step left (str code \0))
right #(sym-step right (str code \1))
:else {:sym sym :weight weight :code code}))]
(trampoline sym-step m "")))
(defn huffman-encode [s]
(->> s init-pq huffman-tree symbol-map flatten))
(defn display-huffman-encode [s]
(->> s huffman-encode (sort-by :weight >) print-table))
(display-huffman-encode "this is an example for huffman encoding")