|
805 | 805 | ###
|
806 | 806 | ###
|
807 | 807 |
|
808 |
| -(defn- median-of-three [a b c] |
809 |
| - (if (not= (> a b) (> a c)) |
810 |
| - a |
811 |
| - (if (not= (> b a) (> b c)) b c))) |
| 808 | +(defmacro- median-of-three |
| 809 | + [x y z] |
| 810 | + ~(if (<= ,x ,y) |
| 811 | + (if (<= ,y ,z) ,y (if (<= ,z ,x) ,x ,z)) |
| 812 | + (if (<= ,z ,y) ,y (if (<= ,x ,z) ,x ,z)))) |
| 813 | + |
| 814 | +(defmacro- sort-partition-template |
| 815 | + [ind before? left right pivot] |
| 816 | + ~(do |
| 817 | + (while (,before? (in ,ind ,left) ,pivot) (++ ,left)) |
| 818 | + (while (,before? ,pivot (in ,ind ,right)) (-- ,right)))) |
812 | 819 |
|
813 | 820 | (defn- sort-help [a lo hi before?]
|
814 | 821 | (when (< lo hi)
|
815 |
| - (def pivot |
816 |
| - (median-of-three (in a hi) (in a lo) |
817 |
| - (in a (math/floor (/ (+ lo hi) 2))))) |
| 822 | + (def [x y z] [(in a lo) |
| 823 | + (in a (div (+ lo hi) 2)) |
| 824 | + (in a hi)]) |
| 825 | + (def pivot (median-of-three x y z)) |
818 | 826 | (var left lo)
|
819 | 827 | (var right hi)
|
820 | 828 | (while true
|
821 |
| - (while (before? (in a left) pivot) (++ left)) |
822 |
| - (while (before? pivot (in a right)) (-- right)) |
| 829 | + (case before? |
| 830 | + < (sort-partition-template a < left right pivot) |
| 831 | + > (sort-partition-template a > left right pivot) |
| 832 | + (sort-partition-template a before? left right pivot)) |
823 | 833 | (when (<= left right)
|
824 | 834 | (def tmp (in a left))
|
825 | 835 | (set (a left) (in a right))
|
826 | 836 | (set (a right) tmp)
|
827 | 837 | (++ left)
|
828 | 838 | (-- right))
|
829 | 839 | (if (>= left right) (break)))
|
830 |
| - (sort-help a lo right before?) |
831 |
| - (sort-help a left hi before?)) |
| 840 | + (if (< lo right) |
| 841 | + (sort-help a lo right before?)) |
| 842 | + (if (< left hi) |
| 843 | + (sort-help a left hi before?))) |
832 | 844 | a)
|
833 | 845 |
|
834 | 846 | (defn sort
|
835 | 847 | ``Sorts `ind` in-place, and returns it. Uses quick-sort and is not a stable sort.
|
836 | 848 | If a `before?` comparator function is provided, sorts elements using that,
|
837 | 849 | otherwise uses `<`.``
|
838 | 850 | [ind &opt before?]
|
839 |
| - (sort-help ind 0 (- (length ind) 1) (or before? <))) |
| 851 | + (default before? <) |
| 852 | + (sort-help ind 0 (- (length ind) 1) before?)) |
840 | 853 |
|
841 | 854 | (defn sort-by
|
842 | 855 | ``Sorts `ind` in-place by calling a function `f` on each element and
|
|
0 commit comments