From 7e6d7b981284b2174ac541ebc51beab700f9e66c Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Thu, 20 Aug 2015 06:12:12 -0600 Subject: [PATCH 1/2] add sort support from @thomasmulvaney --- pixie/stdlib.pxi | 33 +++++++++++++++++++++++++++++++++ pixie/test-sort.pxi | 11 +++++++++++ 2 files changed, 44 insertions(+) create mode 100644 pixie/test-sort.pxi diff --git a/pixie/stdlib.pxi b/pixie/stdlib.pxi index b0d5ec96..1e578d09 100644 --- a/pixie/stdlib.pxi +++ b/pixie/stdlib.pxi @@ -2974,3 +2974,36 @@ ex: (vary-meta x assoc :foo 42)" :added "0.1"} [x f & args] (with-meta x (apply f (meta x) args))) + +;;; Sorting + +(defn -merge-sort-step + [comp-fn merged-left merged-right res] + (cond + (empty? merged-left) (into res merged-right) + (empty? merged-right) (into res merged-left) + :else + (if (neg? (comp-fn (first merged-left) (first merged-right))) + (recur comp-fn (rest merged-left) merged-right (conj res (first merged-left))) + (recur comp-fn merged-left (rest merged-right) (conj res (first merged-right)))))) + +(defn -merge-sort-split + [comp-fn coll] + (if (> (count coll) 1) + (let [[left right] (split-at (/ (count coll) 2) coll)] + (-merge-sort-step comp-fn + (-merge-sort-split comp-fn left) + (-merge-sort-split comp-fn right) + [])) + coll)) + +(defn merge-sort [comp-fn coll] + (-merge-sort-split comp-fn coll)) + +(defn sort + ([coll] + (sort compare coll)) + ([comp-fn coll] + (merge-sort comp-fn coll))) + +;;; End Sorting diff --git a/pixie/test-sort.pxi b/pixie/test-sort.pxi new file mode 100644 index 00000000..f7b2a551 --- /dev/null +++ b/pixie/test-sort.pxi @@ -0,0 +1,11 @@ +(ns pixie.tests.test-sort + (require pixie.test :as t)) + +(t/deftest test-sort + (t/assert= (sort [5 2 3 1 4]) [1 2 3 4 5]) + (t/assert= (sort ["d" "c" "b" "a"]) ["a" "b" "c" "d"]) + (t/assert= (sort [1/1 1/2 1/3 1/4]) [1/4 1/3 1/2 1/1])) + +(t/deftest test-sort-big + (t/assert= (sort (range 10000)) (range 10000)) + (t/assert= (sort (range 9999 -1 -1)) (range 10000))) From 7a94c63c01343987c673e1e2abff18a5b68331f3 Mon Sep 17 00:00:00 2001 From: Thomas Mulvaney Date: Fri, 6 Nov 2015 20:20:58 +0000 Subject: [PATCH 2/2] get sorting working using a trampoline --- pixie/stdlib.pxi | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pixie/stdlib.pxi b/pixie/stdlib.pxi index 1e578d09..0644ab61 100644 --- a/pixie/stdlib.pxi +++ b/pixie/stdlib.pxi @@ -2975,6 +2975,12 @@ ex: (vary-meta x assoc :foo 42)" [x f & args] (with-meta x (apply f (meta x) args))) +(defn trampoline [f] + (let [result (f)] + (if (fn? result) + (recur result) + result))) + ;;; Sorting (defn -merge-sort-step @@ -2992,8 +2998,8 @@ ex: (vary-meta x assoc :foo 42)" (if (> (count coll) 1) (let [[left right] (split-at (/ (count coll) 2) coll)] (-merge-sort-step comp-fn - (-merge-sort-split comp-fn left) - (-merge-sort-split comp-fn right) + (trampoline #(-merge-sort-split comp-fn left)) + (trampoline #(-merge-sort-split comp-fn right)) [])) coll))