mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
Added compare_lists(), compare_vals(), and quicksort()
This commit is contained in:
parent
2b33a87d1c
commit
cdd2989215
1 changed files with 79 additions and 0 deletions
79
math.scad
79
math.scad
|
@ -35,8 +35,10 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
include <compat.scad>
|
||||
|
||||
|
||||
// Function: Cpi()
|
||||
// Status: DEPRECATED, use `PI` instead.
|
||||
// Description:
|
||||
|
@ -528,6 +530,83 @@ function array_group(v, cnt=2, dflt=0) = [for (i = [0:cnt:len(v)-1]) [for (j = [
|
|||
function flatten(l) = [for (a = l) for (b = a) b];
|
||||
|
||||
|
||||
// Function: compare_lists()
|
||||
// Usage:
|
||||
// compare_lists(a, b)
|
||||
// Description:
|
||||
// Compare contents of two lists.
|
||||
// Returns <0 if `a`<`b`.
|
||||
// Returns >0 if `a`>`b`.
|
||||
// Returns 0 if `a`==`b`.
|
||||
// Arguments:
|
||||
// a = First list to compare.
|
||||
// b = Second list to compare.
|
||||
function compare_lists(a, b, n=0) =
|
||||
let (la = len(a), lb = len(b))
|
||||
(la<=n && lb<=n)? 0 :
|
||||
(la<=n)? -1 :
|
||||
(lb<=n)? 1 :
|
||||
let (cmp = compare_vals(a[n], b[n]))
|
||||
(cmp != 0)? cmp :
|
||||
compare_lists(a, b, n+1);
|
||||
|
||||
|
||||
// Function: compare_vals()
|
||||
// Usage:
|
||||
// compare_vals(a, b);
|
||||
// Description:
|
||||
// Compares two values. If types don't match, then
|
||||
// undef < boolean < scalar < string < list
|
||||
// Lists are compared recursively.
|
||||
// Arguments:
|
||||
// a = First value to compare.
|
||||
// b = Second value to compare.
|
||||
function compare_vals(a, b, n=0) =
|
||||
(a == undef && b == undef)? 0 :
|
||||
(a == undef)? -1 :
|
||||
(b == undef)? 1 :
|
||||
(is_boolean(a) && is_boolean(b))? ((a?1:0)-(b?1:0)) :
|
||||
is_boolean(a)? -1 :
|
||||
is_boolean(b)? 1 :
|
||||
(is_scalar(a) && is_scalar(b))? (a-b) :
|
||||
is_scalar(a)? -1 :
|
||||
is_scalar(b)? 1 :
|
||||
(is_str(a) && is_str(b))? ((a<b)? -1 : ((a>b)? 1 : 0)) :
|
||||
is_str(a)? -1 :
|
||||
is_str(b)? 1 :
|
||||
compare_lists(a,b);
|
||||
|
||||
|
||||
|
||||
// Function: quicksort()
|
||||
// Usage:
|
||||
// quicksort(arr, [idx])
|
||||
// Description:
|
||||
// Sorts the given list using `compare_vals()`.
|
||||
// Arguments:
|
||||
// arr = The list to sort.
|
||||
// idx = If given, the index, range, or list of indices of sublist items to compare.
|
||||
// Example:
|
||||
// l = [45,2,16,37,8,3,9,23,89,12,34];
|
||||
// sorted = quicksort(l); // Returns [2,3,8,9,12,16,23,34,37,45,89]
|
||||
function quicksort(arr, idx=undef) =
|
||||
(len(arr)<=1) ? arr :
|
||||
let(
|
||||
pivot = arr[floor(len(arr)/2)],
|
||||
pivotval = idx==undef? pivot : [for (i=idx) pivot[i]],
|
||||
compare = [
|
||||
for (entry = arr) let(
|
||||
val = idx==undef? entry : [for (i=idx) entry[i]]
|
||||
) compare_vals(val, pivotval)
|
||||
],
|
||||
lesser = [ for (i = [0:len(arr)-1]) if (compare[i] < 0) arr[i] ],
|
||||
equal = [ for (i = [0:len(arr)-1]) if (compare[i] ==0) arr[i] ],
|
||||
greater = [ for (i = [0:len(arr)-1]) if (compare[i] > 0) arr[i] ]
|
||||
)
|
||||
concat(quicksort(lesser,idx), equal, quicksort(greater,idx));
|
||||
|
||||
|
||||
|
||||
// Internal. Not exposed.
|
||||
function _array_dim_recurse(v) =
|
||||
!is_list(v[0])? (
|
||||
|
|
Loading…
Reference in a new issue