walk through tree functionally - clojure

I'm try to writemy own "walk through tree" function, but I'm new in FP
I've wrote these function and it works nice, but it looks ugly
(defrecord Tree [value left right])
(defn depth_walk_tree
[tree functor]
(let [item (functor (:value tree))]
(let [leftlst
(if (:left tree)
(cons item (depth_walk_tree (:left tree) functor))
(list item))
]
(if (:right tree)
(concat
leftlst
(depth_walk_tree (:right tree) functor))
leftlst))))
(def tree (Tree. 1 (Tree. 2 (Tree. 0 nil nil) (Tree. 90 nil nil)) (Tree. 3 nil (Tree. 10 nil nil)) ))
(println (depth_walk_tree tree #(+ % 1) ))
Programs answer is
(2 3 1 91 4 11); is Ok
Can anyone advise me how make it beauty?
PS Sorry for my writing mistakes. English in not my native language.

This looks a bit more functional, IMHO:
(defn depth_walk_tree [tree functor]
(concat
(list (functor (:value tree)))
(if (:left tree) (depth_walk_tree (:left tree) functor))
(if (:right tree) (depth_walk_tree (:right tree) functor))))
And it preserves the original result, too:
(depth_walk_tree tree inc)
=> (2 3 1 91 4 11)

Related

Deleting any node inside BST - Clojure

I'm studying algorithms and at the class we were asked to create a BST with structures, I'm trying really hard to create a delete function but the one I created isn't efficient and doesn't work. I searched in google for something similar, but most of the questions are about vectors and not record/structures. If you have any recommendations, I would really appreciate it.
This is the basic creating of the root and node:
(let [bst (make-bst)]
(bst-empty? bst)
(make-bst-node 10))
(defrecord BST [root])
(defn bst? [bst]
(= (class bst) BST))
(defn make-bst []
(BST. (ref nil)))
(defn bst-empty? [bst]
(nil? #(:root bst)))
(defrecord BSTnode [data left right])
(defn make-bst-node [val]
(BSTnode. val (ref nil) (ref nil)))
(defn bst-insert! [bst val]
(loop [node (:root bst)]
(if (nil? #node)
(dosync
(ref-set node (make-bst-node val)))
(let [data (:data bst)]
(if (< val data)
(recur (:left #node))
(if (val data)
(recur (:right #node))))))))
This is the delete function:
(defn bst-del [bst val]
(if (nil? #(:root bst))
false
(do
(if (= (:data #(:root bst)) val)
(if (nil? (and (:right bst) (:left bst)))
(dosync
(ref-set (:root bst) nil))
(if (not (nil? (:right bst)))
(dosync
(ref-set (:root bst) #(:right bst)))
(if (not (nil? (:left bst)))
(dosync
(ref-set (:root bst) #(:left bst)))
(if (not (nil? (and (:right bst) (:left bst))))
(dosync
(ref-set (:root bst) #(:left bst))
(ref-set (:root bst) (:right bst))) false))))))))
(defn node-del [bst val]
(loop [node #(:root bst)]
(if (nil? node)
false
(if (true? bst-del)
(println "somthing got deleted")
(if (< val (:data node))
(recur #(:left node))
(recur #(:right node)))))))
I tried to search in google but all the function or examples were for maps and vectors, not my case, as well as, reading theoretical material about the subject and references from different languages.
this code of yours seems to be overly complicated and hard to debug (or event understand an algorithm)
I would propose implementing this recursive algorithm for deletion, which works quite nice with that mutable structure of yours:
Node delete(root : Node, z : T):
if root == null
return root
if z < root.key
root.left = delete(root.left, z)
else if z > root.key
root.right = delete(root.right, z)
else if root.left != null and root.right != null
root.key = minimum(root.right).key
root.right = delete(root.right, root.key)
else
if root.left != null
root = root.left
else if root.right != null
root = root.right
else
root = null
return root
so, i would start with the following type defs:
(defrecord Tree [root])
(defn make-tree [root-node]
(->Tree (ref root-node)))
(defrecord Node [data left right])
(defn make-node [data & {:keys [left right]}]
(->Node (ref data)
(ref left)
(ref right)))
first thing we want is insertion + traversal functions for tree creating/debug. let's implement them for Node (and employ in Tree later):
(defn insert-node [{:keys [data left right] :as node} item]
(if (nil? node)
(make-node item)
(dosync (alter (if (< item #data) left right)
insert-node
item)
node)))
(defn traverse-node [node]
(when-some [{:keys [data left right]} node]
(concat (traverse-node #left)
[#data]
(traverse-node #right))))
user> (reduce insert-node nil [3 1 2])
;; {:data #<Ref#1a28bd3f: 3>,
;; :left
;; #<Ref#514133ef:
;; {:data #<Ref#5617f393: 1>,
;; :left #<Ref#637de49b: nil>,
;; :right
;; #<Ref#6efa5317:
;; {:data #<Ref#14ef556b: 2>,
;; :left #<Ref#7fe0e031: nil>,
;; :right #<Ref#5a16bba5: nil>}>}>,
;; :right #<Ref#4eec6b9f: nil>}
user> (traverse-node (reduce insert-node nil [3 1 2]))
;; (1 2 3)
so, this seems to work ok.
Next, we will implement the deletion algorithm.
there's an utility function minimum in the aforementioned algorithm, so we start with that one:
(defn minimum-node [{:keys [data left right] :as node}]
(cond (nil? node) nil
(nil? #left) #data
:else (recur #left)))
user> (minimum-node (reduce insert-node nil (shuffle (range 10 20))))
;; 10
after that the deletion implementation looks trivial:
(defn del-node [node item]
(when-some [{:keys [data left right]} node]
(cond (< item #data) (dosync (alter left del-node item)
node)
(> item #data) (dosync (alter right del-node item)
node)
(and (some? #left) (some? #right)) (let [m (-> right deref minimum-node)]
(dosync
(ref-set data m)
(alter right del-node m))
node)
(some? #left) #left
(some? #right) #right)))
user> (traverse-node (del-node
(reduce insert-node nil (shuffle (range 10 20)))
13))
;;=> (10 11 12 14 15 16 17 18 19)
this seems to be working mutable algorithm.
Let's then go back to the Tree structure. I would start with the BST protocol, to be used by both Node and Tree:
(defprotocol BST
(traverse [self])
(insert [self item])
(minimum [self])
(del [self item]))
(extend-protocol BST
Node
(traverse [self]
(traverse-node self))
(insert [self item]
(insert-node self item))
(minimum [self]
(minimum-node self))
(del [self item]
(del-node self item)))
(extend-protocol BST
Tree
(traverse [self] (-> self :root deref traverse))
(insert [self item]
(dosync
(if (-> self :root deref some?)
(alter (:root self) insert item)
(ref-set (:root self) (make-node item))))
self)
(minimum [self] (-> self :root deref minimum))
(del [self item]
(dosync
(when (-> self :root deref some?)
(alter (:root self) del item)))
self))
and that's it. Now just use it:
user> (reduce del
(reduce insert (make-tree nil) [1 2 3 4])
[2 4])
;; {:root
;; #<Ref#273f7854:
;; {:data #<Ref#67d4f4d0: 1>,
;; :left #<Ref#26329ec3: nil>,
;; :right
;; #<Ref#5636f9f8:
;; {:data #<Ref#3cd02119: 3>,
;; :left #<Ref#7d62fb13: nil>,
;; :right #<Ref#1f25eeb7: nil>}>}>}
After the class, I understood how to delete a function and I implemented it similarly inside a dictionary binary tree. It is really similar, the only difference is with "key" value, but the logic is the same.
(defn dict-find-leftmost-node[start-node]
(loop [node start-node]
(if (nil? #(:left #node))
node
(recur (:left #node)))))
(defn dict-remove! [dict key]
(let [node-to-remove (dict-get-node dict key)]
(when (not (nil? node-to-remove))
(if (dict-node-leaf? node-to-remove)
(dosync
(ref-set node-to-remove nil))
(if (nil? #(:left #node-to-remove))
(dosync
;;(println "I need to pull up the right branch")
(ref-set node-to-remove
#(:right #node-to-remove)))
(if (nil? #(:right #node-to-remove))
(dosync
;;(println "I need to pull up the left branch")
(ref-set node-to-remove
#(:left #node-to-remove)))
(let [leftmost-node
(dict-find-leftmost-node
(:right #node-to-remove))]
(dosync
(ref-set (:left #leftmost-node)
#(:left #node-to-remove))
(ref-set node-to-remove
#(:right #node-to-remove))))
;;(println "I don't know what to do yet!")
;; this is where we remove the node
))))))
(defn dict-node-leaf? [node]
(and (nil? #(:left #node))
(nil? #(:right #node))))

How to calculate the sum of all depths in a tree using basic `recur`?

For a given tree I would like to sum the depth of each node and calculate that recursively (so not with map/flatten/sum).
Is there a way to do that with recur or do I need to use a zipper in this case?
recur is for tail recursion, meaning if you could do it with normal recursion, where the return value is exactly what a single recursive call would return, then you can use it.
Most functions on trees cannot be written in a straightforward way when restricted to using only tail recursion. Normal recursive calls are much more straightforward, and as long as the tree depth is not thousands of levels deep, then normal recursive calls are just fine in Clojure.
The reason you may have found recommendations against using normal recursive calls in Clojure is for cases when the call stack could grow to tens or hundreds of thousands of calls deep, e.g. a recursive call one level deep for each element of a sequence that could be tens or hundreds of thousands of elements long. That would exceed the default maximum call stack depth limits of many run-time systems.
Using normal stack consuming recursion you can accomplish this pretty easily, by doing a depth-first traversal and summing the depth on the way back out.
(defn sum-depths
([tree]
(sum-depths tree 0))
([node depth]
(if-not (vector? node)
depth
(do
(apply
+
(for [child-node (second node)]
(sum-depths child-node (inc depth))))))))
(sum-depths [:root
[:a1
[:b1
[:a2 :b2]]
:c1]])
;; => 6
(sum-depths ["COM"
[["B"
[["C"
[["D"
[["E"
["F"
["J"
[["K"
["L"]]]]]]
"I"]]]]
["G"
["H"]]]]]])
;; => 19
The details depend a little bit on how you model your tree, so the above assumes that a node is either a vector pair where the first element is the value and the second element is a vector of children nodes, or if it is a leaf node then it's not a vector.
So a leaf node is anything that's not a vector.
And a node with children is a vector of form: [value [child1 child2 ...]
And here I assumed you wanted to sum the depth of all leaf nodes. Since I see from your answer, that your example gives 42, I'm now thinking you meant the sum of the depth of every node, not just leaves, if so it only takes one extra line of code to do so:
(defn sum-depths
([tree]
(sum-depths tree 0))
([node depth]
(if-not (vector? node)
depth
(do
(apply
+
depth
(for [child-node (second node)]
(sum-depths child-node (inc depth))))))))
(sum-depths [:root
[:a1
[:b1
[:a2 :b2]]
:c1]])
;; => 7
(sum-depths ["COM"
[["B"
[["C"
[["D"
[["E"
["F"
["J"
[["K"
["L"]]]]]]
"I"]]]]
["G"
["H"]]]]]])
;; => 42
And like your own answer showed, this particular algorithm can be solved without a stack as well, by doing a level order traversal (aka breadth-first traversal) of the tree. Here it is working on my tree data-structure (similar strategy then your own answer otherwise):
(defn sum-depths [tree]
(loop [children (second tree) depth 0 total 0]
(if (empty? children)
total
(let [child-depth (inc depth)
level-total (* (count children) child-depth)]
(recur (into [] (comp (filter vector?) (mapcat second)) children)
child-depth
(+ total level-total))))))
(sum-depths [:root
[:a1
[:b1
[:a2 :b2]]
:c1]])
;; => 7
(sum-depths ["COM"
[["B"
[["C"
[["D"
[["E"
["F"
["J"
[["K"
["L"]]]]]]
"I"]]]]
["G"
["H"]]]]]])
;; => 42
And for completeness, I also want to show how you can do a depth-first recursive traversal using core.async instead of the function call stack in order to be able to traverse trees that would cause a StackOverFlow otherwise, but still using a stack based recursive depth-first traversal instead of an iterative one. As an aside, there exists some non stack consuming O(1) space depth-first traversals as well, using threaded trees (Morris algorithm) or tree transformations, but I won't show those as I'm not super familiar with them and I believe they only work on binary trees.
First, let's construct a degenerate tree of depth 10000 which causes a StackOverFlow when run against our original stack-recursive sum-depths:
(def tree
(loop [i 0 t [:a [:b]]]
(if (< i 10000)
(recur (inc i)
[:a [t]])
t)))
(defn sum-depths
([tree]
(sum-depths tree 0))
([node depth]
(if-not (vector? node)
depth
(do
(apply
+
depth
(for [child-node (second node)]
(sum-depths child-node (inc depth))))))))
(sum-depths tree)
;; => java.lang.StackOverflowError
If it works on your machine, try increasing 10000 to something even bigger.
Now we rewrite it to use core.async instead:
(require '[clojure.core.async :as async])
(defmacro for* [[element-sym coll] & body]
`(loop [acc# [] coll# ~coll]
(if-let [~element-sym (first coll#)]
(recur (conj acc# (do ~#body)) (next coll#))
acc#)))
(def tree
(loop [i 0 t [:a [:b]]]
(if (< i 10000)
(recur (inc i)
[:a [t]])
t)))
(defn sum-depths
([tree]
(async/<!! (sum-depths tree 0)))
([node depth]
(async/go
(if-not (vector? node)
depth
(do
(apply
+
depth
(for* [child-node (second node)]
(async/<!
(sum-depths child-node (inc depth))))))))))
;; => (sum-depths tree)
50015001
It is relatively easy to rewrite a stack-recursive algorithm to use core.async instead of the call stack, and thus make it so it isn't at risk of causing a StackOverFlow in the case of large inputs. Just wrap it in a go block, and wrap the recursive calls in a <! and the whole algorithm in a <!!. The only tricky part is that core.async cannot cross function boundaries, which is why the for* macro is used above. The normal Clojure for macro crosses function boundaries internally, and thus we can't use <! inside it. By rewriting it to not do so, we can use <! inside it.
Now for this particular algorithm, the tail-recursive variant using loop/recur is probably best, but I wanted to show this technique of using core.async for posterity, since it can be useful in other cases where there isn't a trivial tail-recursive implementation.
i would also propose this one, which is kinda straightforward:
it uses more or less the same approach, as tail recursive flatten does:
(defn sum-depth
([data] (sum-depth data 1 0))
([[x & xs :as data] curr res]
(cond (empty? data) res
(coll? x) (recur (concat x [:local/up] xs) (inc curr) res)
(= :local/up x) (recur xs (dec curr) res)
:else (recur xs curr (+ res curr)))))
the trick is that when you encounter the collection at the head of the sequence, you concat it to the rest, adding special indicator that signals the end of branch and level up. It allows you to track the current depth value. Quite simple, and also using one pass.
user> (sum-depth [1 [2 7] [3]])
;;=> 7
user> (sum-depth [1 2 3 [[[[[4]]]]]])
;;=> 9
You can use map/mapcat to walk a tree recursively to produce a lazy-seq (of leaf nodes). If you need depth information, just add it along the way.
(defn leaf-seq
[branch? children root]
(let [walk (fn walk [lvl node]
(if (branch? node)
(->> node
children
(mapcat (partial walk (inc lvl))))
[{:lvl lvl
:leaf node}]))]
(walk 0 root)))
To run:
(->> '((1 2 ((3))) (4))
(leaf-seq seq? identity)
(map :lvl)
(reduce +))
;; => 10
where the depths of each node are:
(->> '((1 2 ((3))) (4))
(leaf-seq seq? identity)
(map :lvl))
;; => (2 2 4 2)
Updates - sum all nodes instead of just leaf nodes
I misread the original requirement and was assuming leaf nodes only. To add the branch node back is easy, we just need to cons it before its child sequence.
(defn node-seq
"Returns all the nodes marked with depth/level"
[branch? children root]
(let [walk (fn walk [lvl node]
(lazy-seq
(cons {:lvl lvl
:node node}
(when (branch? node)
(->> node
children
(mapcat (partial walk (inc lvl))))))))]
(walk 0 root)))
Then we can walk on the hiccup-like tree as before:
(->> ["COM" [["B" [["C" [["D" [["E" [["F"] ["J" [["K" [["L"]]]]]]] ["I"]]]]] ["G" [["H"]]]]]]]
(node-seq #(s/valid? ::branch %) second)
(map :lvl)
(reduce +))
;; => 42
Note: above function uses below helper specs to identify the branch/leaf:
(s/def ::leaf (s/coll-of string? :min-count 1 :max-count 1))
(s/def ::branch (s/cat :tag string? :children (s/coll-of (s/or :leaf ::leaf
:branch ::branch))))
Here's my alternative approach that does use recur:
(defn sum-of-depths
[branches]
(loop [branches branches
cur-depth 0
total-depth 0]
(cond
(empty? branches) total-depth
:else (recur
(mapcat (fn [node] (second node)) branches)
(inc cur-depth)
(+ total-depth (* (count branches) cur-depth))))))
(def tree ["COM" (["B" (["C" (["D" (["E" (["F"] ["J" (["K" (["L"])])])] ["I"])])] ["G" (["H"])])])])
(sum-of-depths [tree]) ; For the first call we have to wrap the tree in a list.
=> 42
You can do this using the Tupelo Forest library. Here is a function to extract information about a tree in Hiccup format. First, think about how we want to use the information for a simple tree with 3 nodes:
(dotest
(hid-count-reset)
(let [td (tree-data [:a
[:b 21]
[:c 39]])]
(is= (grab :paths td) [[1003]
[1003 1001]
[1003 1002]])
(is= (grab :node-hids td) [1003 1001 1002])
(is= (grab :tags td) [:a :b :c])
(is= (grab :depths td) [1 2 2])
(is= (grab :total-depth td) 5) ))
Here is how we calculate the above information:
(ns tst.demo.core
(:use tupelo.forest tupelo.core tupelo.test)
(:require
[schema.core :as s]
[tupelo.schema :as tsk]))
(s/defn tree-data :- tsk/KeyMap
"Returns data about a hiccup tree"
[hiccup :- tsk/Vec]
(with-forest (new-forest)
(let [root-hid (add-tree-hiccup hiccup)
paths (find-paths root-hid [:** :*])
node-hids (mapv xlast paths)
tags (mapv #(grab :tag (hid->node %)) node-hids)
depths (mapv count paths)
total-depth (apply + depths)]
(vals->map paths node-hids tags depths total-depth))))
and an example on a larger Hiccup-format tree:
(dotest
(let [td (tree-data [:a
[:b 21]
[:b 22]
[:b
[:c
[:d
[:e
[:f
[:g 7]
[:h
[:i 9]]]]]]
[:c 32]]
[:c 39]])]
(is= (grab :tags td) [:a :b :b :b :c :d :e :f :g :h :i :c :c])
(is= (grab :depths td) [1 2 2 2 3 4 5 6 7 7 8 3 2])
(is= (grab :total-depth td) 52)))
Don't be afraid of stack size for normal processing. On my computer, the default stack doesn't overflow until you get to a stack depth of over 3900 recursive calls. For a binary tree, just 2^30 is over a billion nodes, and 2^300 is more nodes than the number of protons in the universe (approx).

finding the max and min in a tree without using flatten

I need to Develop a function called bounds which takes a nested list of numbers as its only argument (ie: a tree). Bounds should return the largest &smallest value in the tree. Eg:
(bounds '(1 (-2 17 (4) -8 (-6 13) (-8 17))))
Using clojure and not using the flatten function but using recursion to visit each node
(defn maxv [tree]
(cond
(number? tree) tree
(tree? tree)
(let [newmax (maxv (first tree)) ]
;;let newmax be the first in the tree
(if (< newmax (maxv (first (rest tree))))
;; if the next in the tree is smaller
(= (newmax (maxv (first (rest tree)))))
;;change newmax to this
(recur (maxv (rest tree)))))
;; recur through the rest
this is what i have i think i am being too java ish
flatten is very efficient, so there is no benefit in implementing it yourself.
If your nested list is not too big, you could apply (juxt min max) directly to the flattened list:
(defn bounds [coll]
(apply (juxt min max) (flatten coll)))
For large input collections I would recommend using reduce instead of apply:
(defn bounds [coll]
(reduce (fn [[minv maxv :as res] v]
(if res [(min minv v) (max maxv v)] [v v]))
nil
(flatten coll)))
If you really need pure recursive implementation, here is an example for you:
(defn bounds [coll]
(loop [coll coll [minv maxv :as res] nil]
(if-let [[h & ts] (seq coll)]
(if (sequential? h)
(recur (concat h ts) res)
(recur ts (if res [(min minv h) (max maxv h)] [h h])))
res)))
All three implementation will yield you a tuple containing min and max values:
(bounds '(1 (-2 17 (4) -8 (-6 13) (-8 17)))) ; => [-8 17]
Update: note on sum-tree implementation from comments
It's a very bad idea to use multiple recursion in your code, because it'll blow your stack very quickly:
(sum-tree (range 7000)) ; => java.lang.StackOverflowError
Try using tail recursion with recur, or higher-order functions instead:
(defn sum-tree [tree]
(if (number? tree)
tree
(reduce + (map sum-tree tree))))

How to print tree elements ending in "ire" in Clojure?

I am trying to print tree elements in Pre Order (Root, Left and Right) in Clojure for a given tree structure.
Below is the code prints the elements in Pre order, but I am not able to figure out how to apply the condition to check that the string ends with "ire".
I tried using Filter and When as well. Can someone help here please?
(defn preorder [tree]
(if (nil? (:root tree))
(str nil)
(let [v (:root tree)
l (:left tree)
r (:right tree)]
(str v
(str " ")
(str l (str " ") (preorder l))
(str " ")
(str r (str " ")(preorder r))))))
Suggestions:
Algorithm: Generate a sequence of :root values walking the tree.
Use the sequence library, map or filter, to convert it into strings
or filter the nodes as need be.
Data: Use nil values for :left and :right instead of for
:root.
Thus:
(defn preorder [tree]
(if tree
(let [v (:root tree)
l (:left tree)
r (:right tree)]
(cons v (concat (preorder l) (preorder r))))))
For example
(preorder {:root 5, :left {:root 10}})
;(5 10)
(filter even? (preorder {:root 5, :left {:root 10}}))
;(10)
Beware that you will run out of stack if your tree is too deep.

Clojure - sort function

I am trying to write a recursive sort function that sorts a list from low to high (duh). I am currently getting output, just not the correct output. Here is my code:
(defn sort/predicate [pred loi]
(if (empty? loi)
()
(if (= (count loi) 1)
(cons (first loi) (sort pred (rest loi)))
(if (pred (first loi) (first (rest loi)))
(cons (first loi) (sort pred (rest loi)))
(if (pred (first (rest loi)) (first loi))
(cons (first (rest loi)) (sort pred (cons (first loi) (rest (rest loi)))))
(cons (first loi) (sort pred (rest loi))))))))
Basically, I compare the first two elements in the list and, if the first element is smaller I cons it with the result of comparing the next two elements of the list. If the second element of the list is smaller, I cons the second element with the result of sorting the first two elements of the cons of the first element and everything after the second element (sorry if that's hard to follow). Then, when there is only one element left in the list, I throw it on the end and return it. However, there is a bug along the way somewhere because I should get the following:
>(sort/predicate < '(8 2 5 2 3))
(2 2 3 5 8)
but instead, I get:
>(sort/predicate < '(8 2 5 2 3))
(2 5 2 3 8)
I'm pretty new to clojure, so any help is greatly appreciated. Also, I would like to keep my code roughly the same (I don't want to use a sorting function that already exists). Thanks
I don't think this is a very efficient way to sort, but I tried to stay true to your intention:
(defn my-sort [cmp-fn [x & xs]]
(cond
(nil? x) '()
(empty? xs) (list x)
:else (let [[y & ys :as s] (my-sort cmp-fn xs)]
(if (cmp-fn x y)
(cons x s)
(cons y (my-sort cmp-fn (cons x ys)))))))
;; merge sort implementation - recursive sort without stack consuming
(defn merge-sort
([v comp-fn]
(if (< (count v) 2) v
(let [[left right] (split-at (quot (count v) 2) v)]
(loop [result []
sorted-left (merge-sort left comp-fn)
sorted-right (merge-sort right comp-fn)]
(cond
(empty? sorted-left) (into result sorted-right)
(empty? sorted-right) (into result sorted-left)
:else (if (comp-fn 0 (compare (first sorted-left) (first sorted-right)))
(recur (conj result (first sorted-left)) (rest sorted-left) sorted-right)
(recur (conj result (first sorted-right)) sorted-left (rest sorted-right))))))))
([v] (merge-sort v >)))
clojure.core/sort implement by Java more general.
user=> (sort '(8 2 5 2 3))
(2 2 3 5 8)
user=> (sort > '(8 2 5 2 3))
(8 5 3 2 2)
user=> (source sort)
(defn sort
"Returns a sorted sequence of the items in coll. If no comparator is
supplied, uses compare. comparator must implement
java.util.Comparator. If coll is a Java array, it will be modified.
To avoid this, sort a copy of the array."
{:added "1.0"
:static true}
([coll]
(sort compare coll))
([^java.util.Comparator comp coll]
(if (seq coll)
(let [a (to-array coll)]
(. java.util.Arrays (sort a comp))
(seq a))
())))
nil
user=>