From 21a822e9895b3722c3db9add9571c2e577278565 Mon Sep 17 00:00:00 2001 From: Justin Lin Date: Tue, 12 Apr 2022 14:46:42 +0800 Subject: [PATCH] combination of quick sort and insertion sort --- src/util/_impl/_sort_impl.scad | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/util/_impl/_sort_impl.scad b/src/util/_impl/_sort_impl.scad index 8e7dec12..b3d05464 100644 --- a/src/util/_impl/_sort_impl.scad +++ b/src/util/_impl/_sort_impl.scad @@ -1,15 +1,29 @@ use <_vt_default_comparator.scad>; +function _insert(sorted, elem, less, leng, before = [], i = 0) = + i == leng ? [each sorted, elem] : + less(elem, sorted[i]) ? + [each before, elem, each [for(j = [i:leng - 1]) sorted[j]]] : + _insert(sorted, elem, less, leng, [each before, sorted[i]], i + 1); + +function _insert_sort_sub(lt, sorted, less, leng, i = 1) = + i == leng ? sorted : + _insert_sort_sub(lt, _insert(sorted, lt[i], less, len(sorted)), less, leng, i + 1); + +function _insert_sort(lt, less) = + let(leng = len(lt)) + leng == 0 ? lt : _insert_sort_sub(lt, [lt[0]], less, leng); + function _sort(lt, less, gt_eq) = let(leng = len(lt)) - leng <= 1 ? lt : - leng == 2 ? gt_eq(lt[1], lt[0]) ? lt : [lt[1], lt[0]] : - let( - pivot = lt[0], - before = [for(j = 1; j < leng; j = j + 1) if(less(lt[j], pivot)) lt[j]], - after = [for(j = 1; j < leng; j = j + 1) if(gt_eq(lt[j], pivot)) lt[j]] - ) - [each _sort(before, less, gt_eq), pivot, each _sort(after, less, gt_eq)]; + leng <= 7 ? _insert_sort(lt, less) : + // quick sort + let( + pivot = lt[0], + before = [for(j = 1; j < leng; j = j + 1) if(less(lt[j], pivot)) lt[j]], + after = [for(j = 1; j < leng; j = j + 1) if(gt_eq(lt[j], pivot)) lt[j]] + ) + [each _sort(before, less, gt_eq), pivot, each _sort(after, less, gt_eq)]; function _vt_sort(lt) = _sort(lt, function(a, b) lessThan(a, b), function(a, b) greaterThan(a, b) || a == b);