Added compare_lists(), compare_vals(), and quicksort()

This commit is contained in:
Revar Desmera 2019-03-28 02:26:16 -07:00
parent 2b33a87d1c
commit cdd2989215

View file

@ -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])? (