Skip to content

Instantly share code, notes, and snippets.

@ox
Created July 13, 2018 14:00
Show Gist options
  • Save ox/f847bc62f991af1ceda097448bfddab3 to your computer and use it in GitHub Desktop.
Save ox/f847bc62f991af1ceda097448bfddab3 to your computer and use it in GitHub Desktop.
(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