mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-04 03:09:45 +00:00
Merge pull request #253 from RonaldoCMP/master
Sort debugging and optimizing
This commit is contained in:
commit
91aaae800a
2 changed files with 198 additions and 164 deletions
311
arrays.scad
311
arrays.scad
|
@ -19,6 +19,32 @@
|
|||
// Section: List Query Operations
|
||||
|
||||
|
||||
// Function: is_homogeneous()
|
||||
// Usage:
|
||||
// is_homogeneous(list,depth)
|
||||
// Description:
|
||||
// Returns true when the list have elements of same type up to the depth `depth`.
|
||||
// Booleans and numbers are not distinguinshed as of distinct types.
|
||||
// Arguments:
|
||||
// list = the list to check
|
||||
// depth = the lowest level the check is done
|
||||
// Example:
|
||||
// is_homogeneous( [[1,["a"]], [2,["b"]]] ) // Returns true
|
||||
// is_homogeneous( [[1,["a"]], [2,[true]]] ) // Returns false
|
||||
// is_homogeneous( [[1,["a"]], [2,[true]]], 1 ) // Returns true
|
||||
// is_homogeneous( [[1,["a"]], [2,[true]]], 2 ) // Returns false
|
||||
// is_homogeneous( [[1,["a"]], [true,["b"]]] ) // Returns true
|
||||
function is_homogeneous(l, depth) =
|
||||
!is_list(l) || l==[] ? false :
|
||||
let( l0=l[0] )
|
||||
[] == [for(i=[1:len(l)-1]) if( ! _same_type(l[i],l0, depth+1) ) 0 ];
|
||||
|
||||
function _same_type(a,b, depth) =
|
||||
(depth==0) || (a>=b) || (a==b) || (a<=b)
|
||||
|| ( is_list(a) && is_list(b) && len(a)==len(b)
|
||||
&& []==[for(i=idx(a)) if( ! _same_type(a[i],b[i],depth-1) )0] );
|
||||
|
||||
|
||||
// Function: select()
|
||||
// Description:
|
||||
// Returns a portion of a list, wrapping around past the beginning, if end<start.
|
||||
|
@ -597,6 +623,23 @@ function list_fit(array, length, fill) =
|
|||
|
||||
// Section: List Shuffling and Sorting
|
||||
|
||||
|
||||
// returns true for valid index specifications idx in the interval [imin, imax)
|
||||
// note that idx can't have any value greater or EQUAL to imax
|
||||
// this allows imax=INF as a bound to numerical lists
|
||||
function _valid_idx(idx,imin,imax) =
|
||||
is_undef(idx)
|
||||
|| ( is_finite(idx)
|
||||
&& ( is_undef(imin) || idx>=imin )
|
||||
&& ( is_undef(imax) || idx< imax ) )
|
||||
|| ( is_list(idx)
|
||||
&& ( is_undef(imin) || min(idx)>=imin )
|
||||
&& ( is_undef(imax) || max(idx)< imax ) )
|
||||
|| ( is_range(idx)
|
||||
&& ( is_undef(imin) || (idx[1]>0 && idx[0]>=imin ) || (idx[1]<0 && idx[0]<=imax ) )
|
||||
&& ( is_undef(imax) || (idx[1]>0 && idx[2]<=imax ) || (idx[1]<0 && idx[2]>=imin ) ) );
|
||||
|
||||
|
||||
// Function: shuffle()
|
||||
// Description:
|
||||
// Shuffles the input list into random order.
|
||||
|
@ -611,7 +654,8 @@ function shuffle(list) =
|
|||
concat(shuffle(left), shuffle(right));
|
||||
|
||||
|
||||
// Sort a vector of scalar values
|
||||
// Sort a vector of scalar values with the native comparison operator
|
||||
// all elements should have the same type.
|
||||
function _sort_scalars(arr) =
|
||||
len(arr)<=1 ? arr :
|
||||
let(
|
||||
|
@ -623,105 +667,67 @@ function _sort_scalars(arr) =
|
|||
concat( _sort_scalars(lesser), equal, _sort_scalars(greater) );
|
||||
|
||||
|
||||
// Sort a vector of vectors based on the first entry only of each vector
|
||||
function _sort_vectors1(arr) =
|
||||
len(arr)<=1 ? arr :
|
||||
!(len(arr)>0) ? [] :
|
||||
// lexical sort of a homogeneous list of vectors
|
||||
// uses native comparison operator
|
||||
function _sort_vectors(arr, _i=0) =
|
||||
len(arr)<=1 || _i>=len(arr[0]) ? arr :
|
||||
let(
|
||||
pivot = arr[floor(len(arr)/2)],
|
||||
lesser = [ for (y = arr) if (y[0] < pivot[0]) y ],
|
||||
equal = [ for (y = arr) if (y[0] == pivot[0]) y ],
|
||||
greater = [ for (y = arr) if (y[0] > pivot[0]) y ]
|
||||
)
|
||||
concat( _sort_vectors1(lesser), equal, _sort_vectors1(greater) );
|
||||
pivot = arr[floor(len(arr)/2)][_i],
|
||||
lesser = [ for (entry=arr) if (entry[_i] < pivot ) entry ],
|
||||
equal = [ for (entry=arr) if (entry[_i] == pivot ) entry ],
|
||||
greater = [ for (entry=arr) if (entry[_i] > pivot ) entry ]
|
||||
)
|
||||
concat(
|
||||
_sort_vectors(lesser, _i ),
|
||||
_sort_vectors(equal, _i+1 ),
|
||||
_sort_vectors(greater, _i ) );
|
||||
|
||||
|
||||
|
||||
// Sort a vector of vectors based on the first two entries of each vector
|
||||
// Lexicographic order, remaining entries of vector ignored
|
||||
function _sort_vectors2(arr) =
|
||||
len(arr)<=1 ? arr :
|
||||
!(len(arr)>0) ? [] :
|
||||
// lexical sort of a homogeneous list of vectors by the vector components with indices in idxlist
|
||||
// all idxlist indices should be in the range of the vector dimensions
|
||||
// idxlist must be undef or a simple list of numbers
|
||||
// uses native comparison operator
|
||||
function _sort_vectors(arr, idxlist, _i=0) =
|
||||
len(arr)<=1 || ( is_list(idxlist) && _i>=len(idxlist) ) || _i>=len(arr[0]) ? arr :
|
||||
let(
|
||||
pivot = arr[floor(len(arr)/2)],
|
||||
lesser = [ for (y = arr) if (y[0] < pivot[0] || (y[0]==pivot[0] && y[1]<pivot[1])) y ],
|
||||
equal = [ for (y = arr) if (y[0] == pivot[0] && y[1]==pivot[1]) y ],
|
||||
greater = [ for (y = arr) if (y[0] > pivot[0] || (y[0]==pivot[0] && y[1]>pivot[1])) y ]
|
||||
)
|
||||
concat( _sort_vectors2(lesser), equal, _sort_vectors2(greater) );
|
||||
k = is_list(idxlist) ? idxlist[_i] : _i,
|
||||
pivot = arr[floor(len(arr)/2)][k],
|
||||
lesser = [ for (entry=arr) if (entry[k] < pivot ) entry ],
|
||||
equal = [ for (entry=arr) if (entry[k] == pivot ) entry ],
|
||||
greater = [ for (entry=arr) if (entry[k] > pivot ) entry ]
|
||||
)
|
||||
concat(
|
||||
_sort_vectors(lesser, idxlist, _i ),
|
||||
_sort_vectors(equal, idxlist, _i+1),
|
||||
_sort_vectors(greater, idxlist, _i ) );
|
||||
|
||||
|
||||
|
||||
// Sort a vector of vectors based on the first three entries of each vector
|
||||
// Lexicographic order, remaining entries of vector ignored
|
||||
function _sort_vectors3(arr) =
|
||||
len(arr)<=1 ? arr : let(
|
||||
pivot = arr[floor(len(arr)/2)],
|
||||
lesser = [ for (y = arr)
|
||||
if ( y[0] < pivot[0]
|
||||
|| ( y[0]==pivot[0]
|
||||
&& ( y[1]<pivot[1]
|
||||
|| ( y[1]==pivot[1]
|
||||
&& y[2]<pivot[2] ))))
|
||||
y ],
|
||||
equal = [ for (y = arr)
|
||||
if ( y[0] == pivot[0]
|
||||
&& y[1]== pivot[1]
|
||||
&& y[2]==pivot[2] )
|
||||
y ],
|
||||
greater = [ for (y = arr)
|
||||
if ( y[0] > pivot[0]
|
||||
|| ( y[0]==pivot[0]
|
||||
&& ( y[1] > pivot[1]
|
||||
|| ( y[1]==pivot[1]
|
||||
&& y[2] > pivot[2] ))))
|
||||
y ]
|
||||
) concat( _sort_vectors3(lesser), equal, _sort_vectors3(greater) );
|
||||
|
||||
|
||||
// Sort a vector of vectors based on the first four entries of each vector
|
||||
// Lexicographic order, remaining entries of vector ignored
|
||||
function _sort_vectors4(arr) =
|
||||
len(arr)<=1 ? arr : let(
|
||||
pivot = arr[floor(len(arr)/2)],
|
||||
lesser = [ for (y = arr)
|
||||
if ( y[0] < pivot[0]
|
||||
|| ( y[0]==pivot[0]
|
||||
&& ( y[1]<pivot[1]
|
||||
|| ( y[1]==pivot[1]
|
||||
&& ( y[2]<pivot[2]
|
||||
|| ( y[2]==pivot[2]
|
||||
&& y[3]<pivot[3] ))))))
|
||||
y ],
|
||||
equal = [ for (y = arr)
|
||||
if ( y[0] == pivot[0]
|
||||
&& y[1] == pivot[1]
|
||||
&& y[2] == pivot[2]
|
||||
&& y[3] == pivot[3] )
|
||||
y ],
|
||||
greater = [ for (y = arr)
|
||||
if ( y[0] > pivot[0]
|
||||
|| ( y[0]==pivot[0]
|
||||
&& ( y[1]>pivot[1]
|
||||
|| ( y[1]==pivot[1]
|
||||
&& ( y[2]>pivot[2]
|
||||
|| ( y[2]==pivot[2]
|
||||
&& y[3]>pivot[3] ))))))
|
||||
y ]
|
||||
) concat( _sort_vectors4(lesser), equal, _sort_vectors4(greater) );
|
||||
|
||||
|
||||
// when idx==undef, returns the sorted array
|
||||
// otherwise, returns the indices of the sorted array
|
||||
function _sort_general(arr, idx=undef) =
|
||||
// sorting using compare_vals(); returns indexed list when `indexed==true`
|
||||
function _sort_general(arr, idx=undef, indexed=false) =
|
||||
(len(arr)<=1) ? arr :
|
||||
is_undef(idx)
|
||||
? _sort_scalar(arr)
|
||||
: let( arrind=[for(k=[0:len(arr)-1], ark=[arr[k]]) [ k, [for (i=idx) ark[i]] ] ] )
|
||||
_indexed_sort(arrind);
|
||||
! indexed && is_undef(idx)
|
||||
? _lexical_sort(arr)
|
||||
: let( arrind = _indexed_sort(enumerate(arr,idx)) )
|
||||
indexed
|
||||
? arrind
|
||||
: [for(i=arrind) arr[i]];
|
||||
|
||||
// lexical sort using compare_vals()
|
||||
function _lexical_sort(arr) =
|
||||
arr==[] ? [] : len(arr)==1? arr :
|
||||
let( pivot = arr[floor(len(arr)/2)] )
|
||||
let(
|
||||
lesser = [ for (entry=arr) if (compare_vals(entry, pivot) <0 ) entry ],
|
||||
equal = [ for (entry=arr) if (compare_vals(entry, pivot)==0 ) entry ],
|
||||
greater = [ for (entry=arr) if (compare_vals(entry, pivot) >0 ) entry ]
|
||||
)
|
||||
concat(_lexical_sort(lesser), equal, _lexical_sort(greater));
|
||||
|
||||
|
||||
// given a list of pairs, return the first element of each pair of the list sorted by the second element of the pair
|
||||
// the sorting is done using compare_vals()
|
||||
function _indexed_sort(arrind) =
|
||||
arrind==[] ? [] : len(arrind)==1? [arrind[0][0]] :
|
||||
arrind==[] ? [] : len(arrind)==1? [arrind[0][0]] :
|
||||
let( pivot = arrind[floor(len(arrind)/2)][1] )
|
||||
let(
|
||||
lesser = [ for (entry=arrind) if (compare_vals(entry[1], pivot) <0 ) entry ],
|
||||
|
@ -731,52 +737,46 @@ function _indexed_sort(arrind) =
|
|||
concat(_indexed_sort(lesser), equal, _indexed_sort(greater));
|
||||
|
||||
|
||||
// returns true for valid index specifications idx in the interval [imin, imax)
|
||||
// note that idx can't have any value greater or EQUAL to imax
|
||||
function _valid_idx(idx,imin,imax) =
|
||||
is_undef(idx)
|
||||
|| ( is_finite(idx) && idx>=imin && idx< imax )
|
||||
|| ( is_list(idx) && min(idx)>=imin && max(idx)< imax )
|
||||
|| ( valid_range(idx) && idx[0]>=imin && idx[2]< imax );
|
||||
|
||||
|
||||
// Function: sort()
|
||||
// Usage:
|
||||
// sort(list, [idx])
|
||||
// Description:
|
||||
// Sorts the given list using `compare_vals()`, sorting in lexicographic order, with types ordered according to
|
||||
// Sorts the given list in lexicographic order. If the input is a homogeneous simple list or a homogeneous
|
||||
// list of vectors (see function is_homogeneous), the sorting method uses the native comparison operator and is faster.
|
||||
// When sorting non homogeneous list the elements are compared with `compare_vals`, with types ordered according to
|
||||
// `undef < boolean < number < string < list`. Comparison of lists is recursive.
|
||||
// If the list is a list of vectors whose length is from 1 to 4 and the `idx` parameter is not passed, then
|
||||
// `sort` uses a much more efficient method for comparisons and will run much faster. In this case, all entries
|
||||
// in the data are compared using the native comparison operator, so comparisons between types will fail.
|
||||
// When comparing vectors, homogeneous or not, the parameter `idx` may be used to select the components to compare.
|
||||
// Note that homogeneous lists of vectors may contain mixed types provided that for any two list elements
|
||||
// list[i] and list[j] satisfies type(list[i][k])==type(list[j][k]) for all k.
|
||||
// Strings are allowed as any list element and are compared with the native operators although no substring
|
||||
// comparison is possible.
|
||||
// Arguments:
|
||||
// list = The list to sort.
|
||||
// idx = If given, do the comparison based just on the specified index, range or list of indices.
|
||||
// Example:
|
||||
// l = [45,2,16,37,8,3,9,23,89,12,34];
|
||||
// sorted = sort(l); // Returns [2,3,8,9,12,16,23,34,37,45,89]
|
||||
function sort(list, idx=undef) =
|
||||
// Example:
|
||||
// // Homogeneous lists
|
||||
// l1 = [45,2,16,37,8,3,9,23,89,12,34];
|
||||
// sorted1 = sort(l1); // Returns [2,3,8,9,12,16,23,34,37,45,89]
|
||||
// l2 = [["oat",0], ["cat",1], ["bat",3], ["bat",2], ["fat",3]];
|
||||
// sorted2 = sort(l2); // Returns: [["bat",2],["bat",3],["cat",1],["fat",3],["oat",0]]
|
||||
// // Non-homegenous list
|
||||
// l3 = [[4,0],[7],[3,9],20,[4],[3,1],[8]];
|
||||
// sorted3 = sort(l3); // Returns: [20,[3,1],[3,9],[4],[4,0],[7],[8]]
|
||||
function sort(list, idx=undef) =
|
||||
!is_list(list) || len(list)<=1 ? list :
|
||||
is_def(idx)
|
||||
? assert( _valid_idx(idx,0,len(list)) , "Invalid indices.")
|
||||
let( sarr = _sort_general(list,idx) )
|
||||
[for(i=[0:len(sarr)-1]) list[sarr[i]] ]
|
||||
: let(size = array_dim(list))
|
||||
len(size)==1 ? _sort_scalars(list) :
|
||||
len(size)==2 && size[1] <=4
|
||||
? (
|
||||
size[1]==0 ? list :
|
||||
size[1]==1 ? _sort_vectors1(list) :
|
||||
size[1]==2 ? _sort_vectors2(list) :
|
||||
size[1]==3 ? _sort_vectors3(list)
|
||||
/*size[1]==4*/ : _sort_vectors4(list)
|
||||
)
|
||||
: _sort_general(list);
|
||||
|
||||
is_homogeneous(list,1)
|
||||
? let(size = array_dim(list[0]))
|
||||
size==0 ? _sort_scalars(list)
|
||||
: len(size)!=1 ? _sort_general(list,idx)
|
||||
: is_undef(idx) ? _sort_vectors(list)
|
||||
: assert( _valid_idx(idx) , "Invalid indices.")
|
||||
_sort_vectors(list,[for(i=idx) i])
|
||||
: _sort_general(list,idx);
|
||||
|
||||
|
||||
// Function: sortidx()
|
||||
// Description:
|
||||
// Given a list, calculates the sort order of the list, and returns
|
||||
// Given a list, sort it as function `sort()`, and returns
|
||||
// a list of indexes into the original list in that sorted order.
|
||||
// If you iterate the returned list in order, and use the list items
|
||||
// to index into the original list, you will be iterating the original
|
||||
|
@ -795,31 +795,28 @@ function sort(list, idx=undef) =
|
|||
// idxs1 = sortidx(lst, idx=1); // Returns: [3,0,2,1]
|
||||
// idxs2 = sortidx(lst, idx=0); // Returns: [1,2,0,3]
|
||||
// idxs3 = sortidx(lst, idx=[1,3]); // Returns: [3,0,2,1]
|
||||
function sortidx(list, idx=undef) =
|
||||
assert( is_list(list) || is_string(list) , "Invalid input to sort." )
|
||||
assert( _valid_idx(idx,0,len(list)) , "Invalid indices.")
|
||||
list==[] ? [] :
|
||||
let(
|
||||
size = array_dim(list),
|
||||
aug = is_undef(idx) && (len(size) == 1 || (len(size) == 2 && size[1]<=4))
|
||||
? zip(list, list_range(len(list)))
|
||||
: 0
|
||||
)
|
||||
is_undef(idx) && len(size) == 1? subindex(_sort_vectors1(aug),1) :
|
||||
is_undef(idx) && len(size) == 2 && size[1] <=4
|
||||
? (
|
||||
size[1]==0 ? list_range(len(arr)) :
|
||||
size[1]==1 ? subindex(_sort_vectors1(aug),1) :
|
||||
size[1]==2 ? subindex(_sort_vectors2(aug),2) :
|
||||
size[1]==3 ? subindex(_sort_vectors3(aug),3)
|
||||
/*size[1]==4*/ : subindex(_sort_vectors4(aug),4)
|
||||
)
|
||||
: // general case
|
||||
_sort_general(list,idx);
|
||||
|
||||
|
||||
// sort() does not accept strings but sortidx does; isn't inconsistent ?
|
||||
|
||||
function sortidx(list, idx=undef) =
|
||||
!is_list(list) || len(list)<=1 ? list :
|
||||
is_homogeneous(list,1)
|
||||
? let(
|
||||
size = array_dim(list[0]),
|
||||
aug = ! (size==0 || len(size)==1) ? 0 // for general sorting
|
||||
: [for(i=[0:len(list)-1]) concat(i,list[i])], // for scalar or vector sorting
|
||||
lidx = size==0? [1] : // scalar sorting
|
||||
len(size)==1
|
||||
? is_undef(idx) ? [for(i=[0:len(list[0])-1]) i+1] // vector sorting
|
||||
: [for(i=idx) i+1] // vector sorting
|
||||
: 0 // just to signal
|
||||
)
|
||||
assert( ! ( size==0 && is_def(idx) ),
|
||||
"The specification of `idx` is incompatible with scalar sorting." )
|
||||
assert( _valid_idx(idx) , "Invalid indices." )
|
||||
lidx!=0
|
||||
? let( lsort = _sort_vectors(aug,lidx) )
|
||||
[for(li=lsort) li[0] ]
|
||||
: _sort_general(list,idx,indexed=true)
|
||||
: _sort_general(list,idx,indexed=true);
|
||||
|
||||
|
||||
// Function: unique()
|
||||
// Usage:
|
||||
|
@ -1241,16 +1238,22 @@ function full_flatten(l) = [for(a=l) if(is_list(a)) (each full_flatten(a)) else
|
|||
// Internal. Not exposed.
|
||||
function _array_dim_recurse(v) =
|
||||
!is_list(v[0])
|
||||
? sum( [for(entry=v) is_list(entry) ? 1 : 0] ) == 0 ? [] : [undef]
|
||||
? len( [for(entry=v) if(!is_list(entry)) 0] ) == 0 ? [] : [undef]
|
||||
: let(
|
||||
firstlen = len(v[0]),
|
||||
first = sum( [for(entry = v) len(entry) == firstlen ? 0 : 1] ) == 0 ? firstlen : undef,
|
||||
firstlen = is_list(v[0]) ? len(v[0]): undef,
|
||||
first = len( [for(entry = v) if(! is_list(entry) || (len(entry) != firstlen)) 0 ] ) == 0 ? firstlen : undef,
|
||||
leveldown = flatten(v)
|
||||
)
|
||||
is_list(leveldown[0])
|
||||
? concat([first],_array_dim_recurse(leveldown))
|
||||
: [first];
|
||||
|
||||
function _array_dim_recurse(v) =
|
||||
let( alen = [for(vi=v) is_list(vi) ? len(vi): -1] )
|
||||
v==[] || max(alen)==-1 ? [] :
|
||||
let( add = max(alen)!=min(alen) ? undef : alen[0] )
|
||||
concat( add, _array_dim_recurse(flatten(v)));
|
||||
|
||||
|
||||
// Function: array_dim()
|
||||
// Usage:
|
||||
|
@ -1281,6 +1284,8 @@ function array_dim(v, depth=undef) =
|
|||
? len(v)
|
||||
: let( dimlist = _array_dim_recurse(v))
|
||||
(depth > len(dimlist))? 0 : dimlist[depth-1] ;
|
||||
|
||||
|
||||
|
||||
// This function may return undef!
|
||||
|
||||
|
|
|
@ -3,6 +3,16 @@ include <../std.scad>
|
|||
|
||||
// Section: List Query Operations
|
||||
|
||||
module test_is_homogeneous(){
|
||||
assert(is_homogeneous([[1,["a"]], [2,["b"]]])==true);
|
||||
assert(is_homogeneous([[1,["a"]], [2,[true]]])==false);
|
||||
assert(is_homogeneous([[1,["a"]], [2,[true]]],1)==true);
|
||||
assert(is_homogeneous([[1,["a"]], [2,[true]]],2)==false);
|
||||
assert(is_homogeneous([[1,["a"]], [true,["b"]]])==true);
|
||||
}
|
||||
test_is_homogeneous();
|
||||
|
||||
|
||||
module test_select() {
|
||||
l = [3,4,5,6,7,8,9];
|
||||
assert(select(l, 5, 6) == [8,9]);
|
||||
|
@ -46,7 +56,6 @@ test_in_list();
|
|||
module test_min_index() {
|
||||
assert(min_index([5,3,9,6,2,7,8,2,1])==8);
|
||||
assert(min_index([5,3,9,6,2,7,8,2,7],all=true)==[4,7]);
|
||||
// assert(min_index([],all=true)==[]);
|
||||
}
|
||||
test_min_index();
|
||||
|
||||
|
@ -54,7 +63,6 @@ test_min_index();
|
|||
module test_max_index() {
|
||||
assert(max_index([5,3,9,6,2,7,8,9,1])==2);
|
||||
assert(max_index([5,3,9,6,2,7,8,9,7],all=true)==[2,7]);
|
||||
// assert(max_index([],all=true)==[]);
|
||||
}
|
||||
test_max_index();
|
||||
|
||||
|
@ -74,6 +82,7 @@ module test_list_decreasing() {
|
|||
}
|
||||
test_list_decreasing();
|
||||
|
||||
|
||||
// Section: Basic List Generation
|
||||
|
||||
module test_repeat() {
|
||||
|
@ -155,7 +164,6 @@ module test_list_remove() {
|
|||
}
|
||||
test_list_remove();
|
||||
|
||||
|
||||
module test_list_remove_values() {
|
||||
animals = ["bat", "cat", "rat", "dog", "bat", "rat"];
|
||||
assert(list_remove_values(animals, "rat") == ["bat","cat","dog","bat","rat"]);
|
||||
|
@ -258,15 +266,24 @@ test_shuffle();
|
|||
|
||||
module test_sort() {
|
||||
assert(sort([7,3,9,4,3,1,8]) == [1,3,3,4,7,8,9]);
|
||||
assert(sort(["cat", "oat", "sat", "bat", "vat", "rat", "pat", "mat", "fat", "hat", "eat"]) == ["bat", "cat", "eat", "fat", "hat", "mat", "oat", "pat", "rat", "sat", "vat"]);
|
||||
assert(sort([[4,0],[7],[3,9],20,[4],[3,1],[8]]) == [20,[3,1],[3,9],[4],[4,0],[7],[8]]);
|
||||
assert(sort([[4,0],[7],[3,9],20,[4],[3,1],[8]],idx=1) == [[7],20,[4],[8],[4,0],[3,1],[3,9]]);
|
||||
assert(sort([[8,6],[3,1],[9,2],[4,3],[3,4],[1,5],[8,0]]) == [[1,5],[3,1],[3,4],[4,3],[8,0],[8,6],[9,2]]);
|
||||
assert(sort([[8,0],[3,1],[9,2],[4,3],[3,4],[1,5],[8,6]],idx=1) == [[8,0],[3,1],[9,2],[4,3],[3,4],[1,5],[8,6]]);
|
||||
assert(sort(["cat", "oat", "sat", "bat", "vat", "rat", "pat", "mat", "fat", "hat", "eat"])
|
||||
== ["bat", "cat", "eat", "fat", "hat", "mat", "oat", "pat", "rat", "sat", "vat"]);
|
||||
assert(sort(enumerate([[2,3,4],[1,2,3],[2,4,3]]),idx=1)==[[1,[1,2,3]], [0,[2,3,4]], [2,[2,4,3]]]);
|
||||
assert(sort([0,"1",[1,0],2,"a",[1]])== [0,2,"1","a",[1],[1,0]]);
|
||||
assert(sort([["oat",0], ["cat",1], ["bat",3], ["bat",2], ["fat",3]])== [["bat",2],["bat",3],["cat",1],["fat",3],["oat",0]]);
|
||||
}
|
||||
test_sort();
|
||||
|
||||
|
||||
module test_sortidx() {
|
||||
lst1 = ["d","b","e","c"];
|
||||
lst1 = ["da","bax","eaw","cav"];
|
||||
assert(sortidx(lst1) == [1,3,0,2]);
|
||||
lst5 = [3,5,1,7];
|
||||
assert(sortidx(lst5) == [2,0,1,3]);
|
||||
lst2 = [
|
||||
["foo", 88, [0,0,1], false],
|
||||
["bar", 90, [0,1,0], true],
|
||||
|
@ -276,11 +293,22 @@ module test_sortidx() {
|
|||
assert(sortidx(lst2, idx=1) == [3,0,2,1]);
|
||||
assert(sortidx(lst2, idx=0) == [1,2,0,3]);
|
||||
assert(sortidx(lst2, idx=[1,3]) == [3,0,2,1]);
|
||||
lst3 = [[-4, 0, 0], [0, 0, -4], [0, -4, 0], [-4, 0, 0], [0, -4, 0], [0, 0, 4], [0, 0, -4], [0, 4, 0], [4, 0, 0], [0, 0, 4], [0, 4, 0], [4, 0, 0]];
|
||||
lst3 = [[-4,0,0],[0,0,-4],[0,-4,0],[-4,0,0],[0,-4,0],[0,0,4],
|
||||
[0,0,-4],[0,4,0],[4,0,0],[0,0,4],[0,4,0],[4,0,0]];
|
||||
assert(sortidx(lst3)==[0,3,2,4,1,6,5,9,7,10,8,11]);
|
||||
assert(sortidx([[4,0],[7],[3,9],20,[4],[3,1],[8]]) == [3,5,2,4,0,1,6]);
|
||||
assert(sortidx([[4,0],[7],[3,9],20,[4],[3,1],[8]],idx=1) == [1,3,4,6,0,5,2]);
|
||||
lst4=[0,"1",[1,0],2,"a",[1]];
|
||||
assert(sortidx(lst4)== [0,3,1,4,5,2]);
|
||||
assert(sortidx(["cat","oat","sat","bat","vat","rat","pat","mat","fat","hat","eat"])
|
||||
== [3,0,10,8,9,7,1,6,5,2,4]);
|
||||
assert(sortidx([["oat",0], ["cat",1], ["bat",3], ["bat",2], ["fat",3]])== [3,2,1,4,0]);
|
||||
assert(sortidx(["Belfry", "OpenScad", "Library", "Documentation"])==[0,3,2,1]);
|
||||
assert(sortidx(["x",1,[],0,"abc",true])==[5,3,1,4,0,2]);
|
||||
}
|
||||
test_sortidx();
|
||||
|
||||
|
||||
module test_unique() {
|
||||
assert(unique([]) == []);
|
||||
assert(unique([8]) == [8]);
|
||||
|
@ -336,10 +364,8 @@ module test_set_intersection() {
|
|||
test_set_intersection();
|
||||
|
||||
|
||||
|
||||
// Arrays
|
||||
|
||||
|
||||
module test_add_scalar() {
|
||||
assert(add_scalar([1,2,3],3) == [4,5,6]);
|
||||
assert(add_scalar([[1,2,3],[3,4,5]],3) == [[4,5,6],[6,7,8]]);
|
||||
|
@ -473,6 +499,12 @@ module test_array_dim() {
|
|||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 0) == 2);
|
||||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]], 2) == 3);
|
||||
assert(array_dim([[[1,2,3],[4,5,6]],[[7,8,9]]]) == [2,undef,3]);
|
||||
assert(array_dim([1,2,3,4,5,6,7,8,9]) == [9]);
|
||||
assert(array_dim([[1],[2],[3],[4],[5],[6],[7],[8],[9]]) == [9,1]);
|
||||
assert(array_dim([]) == [0]);
|
||||
assert(array_dim([[]]) == [1,0]);
|
||||
assert(array_dim([[],[]]) == [2,0]);
|
||||
assert(array_dim([[],[1]]) == [2,undef]);
|
||||
}
|
||||
test_array_dim();
|
||||
|
||||
|
@ -486,7 +518,4 @@ module test_transpose() {
|
|||
test_transpose();
|
||||
|
||||
|
||||
cube();
|
||||
|
||||
|
||||
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
||||
|
|
Loading…
Reference in a new issue