Created
July 13, 2018 14:00
-
-
Save ox/f847bc62f991af1ceda097448bfddab3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(def cordMax 4) | |
(defrecord Cord [data weight left right]) | |
(defn print-cord | |
([root] (print-cord root 0)) | |
([root level] | |
(println (apply str (repeat level " ")) (get root :data "") (get root :weight "")) | |
(when-let [left (:left root)] (print-cord left (+ 2 level))) | |
(when-let [right (:right root)] (print-cord right (+ 2 level))))) | |
(defn tree-weight [root] | |
"Calculate the wight of a tree, starting from it's root. The weight is the sum of all of the | |
weights of the leaf nodes." | |
(if (nil? root) | |
0 | |
(if (and (nil? (:left root)) (nil? (:right root))) | |
(:weight root) | |
(+ (tree-weight (:left root)) (tree-weight (:right root)))))) | |
(assert (= (tree-weight nil) 0)) | |
(assert (= (tree-weight {:weight 1}) 1)) | |
(assert (= (tree-weight {:left {:weight 1} :right {:weight 1}}) 2)) | |
(assert (= (tree-weight {:left {:weight 1} :right {:left {:right {:weight 1}}}}) 2)) | |
(defn node-weight [root] | |
"Calculates the weight of a node. | |
The weight of a node is the total string length in its left subtree for a non-leaf node, or the | |
string length of itself for a leaf node." | |
(if (nil? (:left root)) | |
(:weight root) | |
(tree-weight (:left root)))) | |
(assert (= 1 (node-weight {:weight 1}))) | |
(assert (= 1 (node-weight {:left {:weight 1}}))) | |
(assert (= 9 (node-weight {:left {:left {:weight 6} :right {:weight 3}}}))) | |
(defn concat-cord [left right] | |
"Concatenates two cords ('strings') by making a new node as the root of the left and right cords" | |
(map->Cord {:weight (node-weight left) :left left :right right})) | |
(defn build-cord [input] | |
"Builds a tree of cords given some input text" | |
(let [strLength (count input) | |
middle (quot strLength 2) | |
[left right] (split-at middle input)] | |
(if (or (empty? left) (<= strLength cordMax)) | |
(map->Cord {:weight strLength :data input}) | |
(map->Cord {:weight strLength ;; THIS IS WRONG (needs to be half of ORIGINAL string length to left of this node) | |
:left (build-cord left) | |
:right (build-cord right)})) | |
)) | |
(defn cord-from-string [input] | |
(let [c (build-cord input)] | |
(map->Cord {:weight (count input) :left c}))) | |
(assert | |
(let [s "Hello my name is Simon" | |
weight (count s)] | |
(= weight (:weight (cord-from-string s))))) | |
(let [c (cord-from-string "Hello my name is Simon")] | |
(println "node-weight1:" (node-weight c)) | |
(print-cord c)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment