Added closed option to deduplicate(). Fixed inconsistent indentation.

This commit is contained in:
Revar Desmera 2019-07-18 21:24:32 -07:00
parent 5abc7db530
commit 959781d6fe

View File

@ -158,15 +158,20 @@ function reverse(list) = [ for (i = [len(list)-1 : -1 : 0]) list[i] ];
// This is different from `unique()` in that the list is *not* sorted.
// Arguments:
// list = The list to deduplicate.
// closed = If true, drops trailing items if they match the first list item.
// eps = The maximum difference to allow between numbers or vectors.
// Examples:
// deduplicate([8,3,4,4,4,8,2,3,3,7]); // Returns: [8,3,4,8,2,3,7]
// deduplicate([8,3,4,4,4,8,2,3,3,8,8]); // Returns: [8,3,4,8,2,3,8]
// deduplicate(closed=true, [8,3,4,4,4,8,2,3,3,8,8]); // Returns: [8,3,4,8,2,3]
// deduplicate("Hello"); // Returns: ["H","e","l","o"]
// deduplicate([[3,4],[7,2],[7,1.99],[1,4]],eps=0.1); // Returns: [[3,4],[7,2],[1,4]]
function deduplicate(list, eps=EPSILON) =
(is_num(list[0]) || is_vector(list[0]))?
[for (i=[0:1:len(list)-1]) if (!approx(list[i], list[i+1], eps)) list[i]] :
[for (i=[0:1:len(list)-1]) if (list[i] != list[i+1]) list[i]];
function deduplicate(list, closed=false, eps=EPSILON) =
let(
l = len(list),
end = l-(closed?0:1)
) (is_num(list[0]) || is_vector(list[0]))?
[for (i=[0:1:l-1]) if (i==end || !approx(list[i], list[(i+1)%l], eps)) list[i]] :
[for (i=[0:1:l-1]) if (i==end || list[i] != list[(i+1)%l]) list[i]];
// Function: list_set()
@ -283,7 +288,9 @@ function list_bset(indexset, valuelist, dflt=0) =
// list_increasing(list)
// Description:
// Returns true if the list is (non-strictly) increasing
function list_increasing(list,ind=0) = ind < len(list)-1 && list[ind]<=list[ind+1] ? list_increasing(list,ind+1) :
function list_increasing(list,ind=0) =
(ind < len(list)-1 && list[ind]<=list[ind+1])?
list_increasing(list,ind+1) :
(ind>=len(list)-1 ? true : false);
@ -291,7 +298,9 @@ function list_increasing(list,ind=0) = ind < len(list)-1 && list[ind]<=list[ind+
// Usage:
// list_increasing(list)
// Description: returns true if the list is (non-strictly) decreasing
function list_decreasing(list,ind=0) = ind < len(list)-1 && list[ind]>=list[ind+1] ? list_increasing(list,ind+1) :
function list_decreasing(list,ind=0) =
(ind < len(list)-1 && list[ind]>=list[ind+1])?
list_increasing(list,ind+1) :
(ind>=len(list)-1 ? true : false);
@ -395,70 +404,119 @@ function shuffle(list) =
// Sort a vector of scalar values
function _sort_scalars(arr) =
len(arr)<=1 ? arr :
let( pivot = arr[floor(len(arr)/2)],
len(arr)<=1 ? arr : let(
pivot = arr[floor(len(arr)/2)],
lesser = [ for (y = arr) if (y < pivot) y ],
equal = [ for (y = arr) if (y == pivot) y ],
greater = [ for (y = arr) if (y > pivot) y ]
)
concat( _sort_scalars(lesser), equal, _sort_scalars(greater) );
) 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) ? [] :
let( pivot = arr[floor(len(arr)/2)],
!(len(arr)>0) ? [] : 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) );
) concat( _sort_vectors1(lesser), equal, _sort_vectors1(greater) );
// 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) ? [] :
let( pivot = arr[floor(len(arr)/2)],
!(len(arr)>0) ? [] : 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) );
) concat( _sort_vectors2(lesser), equal, _sort_vectors2(greater) );
// 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]
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]
)
concat( _sort_vectors3(lesser), equal, _sort_vectors3(greater) );
)
)
) 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 ]
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]
)
concat( _sort_vectors4(lesser), equal, _sort_vectors4(greater) );
)
)
)
)
) 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) );
function _sort_general(arr, idx=undef) =
@ -505,9 +563,7 @@ function sort(list, idx=undef) =
size[1]==2 ? _sort_vectors2(list) :
size[1]==3 ? _sort_vectors3(list) :
/*size[1]==4*/ _sort_vectors4(list)
) :
_sort_general(list);
) : _sort_general(list);
// Function: sortidx()
@ -532,10 +588,10 @@ function sort(list, idx=undef) =
// 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) =
list==[] ? [] :
let(
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))) :
aug = is_undef(idx) && (len(size) == 1 || (len(size) == 2 && size[1]<=4))?
zip(list, list_range(len(list))) :
enumerate(list,idx=idx)
)
is_undef(idx) && len(size) == 1? subindex(_sort_vectors1(aug),1) :