mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
commit
27754b2725
5 changed files with 211 additions and 133 deletions
40
arrays.scad
40
arrays.scad
|
@ -200,6 +200,24 @@ function list_tail(list, from=1) =
|
|||
list;
|
||||
|
||||
|
||||
// Function: list()
|
||||
// Topics: List Handling, Type Conversion
|
||||
// Usage:
|
||||
// list = list(l)
|
||||
// Description:
|
||||
// Expands a range into a full list. If given a list, returns it verbatim.
|
||||
// If given a string, explodes it into a list of single letters.
|
||||
// Arguments:
|
||||
// l = The value to expand.
|
||||
// See Also: scalar_vec3(), force_list(), range(), rangex()
|
||||
// Example:
|
||||
// l1 = list([3:2:9]); // Returns: [3,5,7,9]
|
||||
// l2 = list([3,4,5]); // Returns: [3,4,5]
|
||||
// l3 = list("Foo"); // Returns: ["F","o","o"]
|
||||
// l4 = list(23); // Returns: [23]
|
||||
function list(l) = is_list(l)? l : [for (x=l) x];
|
||||
|
||||
|
||||
// Function: force_list()
|
||||
// Usage:
|
||||
// list = force_list(value, <n>, <fill>);
|
||||
|
@ -274,20 +292,28 @@ function in_list(val,list,idx) =
|
|||
// Description:
|
||||
// Finds the first item in `list` that matches `val`, returning the index.
|
||||
// Arguments:
|
||||
// val = The value to search for.
|
||||
// val = The value to search for. If given a function literal of signature `function (x)`, uses that function to check list items. Returns true for a match.
|
||||
// list = The list to search through.
|
||||
// ---
|
||||
// start = The index to start searching from.
|
||||
// all = If true, returns a list of all matching item indices.
|
||||
// eps = The maximum allowed floating point rounding error for numeric comparisons.
|
||||
function find_first_match(val, list, start=0, all=false, eps=EPSILON) =
|
||||
all? [for (i=[start:1:len(list)-1]) if(val==list[i] || approx(val, list[i], eps=eps)) i] :
|
||||
all? [
|
||||
for (i=[start:1:len(list)-1])
|
||||
if (
|
||||
(!is_func(val) && approx(val, list[i], eps=eps)) ||
|
||||
(is_func(val) && val(list[i]))
|
||||
) i
|
||||
] :
|
||||
__find_first_match(val, list, eps=eps, i=start);
|
||||
|
||||
function __find_first_match(val, list, eps, i=0) =
|
||||
i >= len(list)? undef :
|
||||
approx(val, list[i], eps=eps)? i :
|
||||
__find_first_match(val, list, eps=eps, i=i+1);
|
||||
(
|
||||
(!is_func(val) && approx(val, list[i], eps=eps)) ||
|
||||
(is_func(val) && val(list[i]))
|
||||
)? i : __find_first_match(val, list, eps=eps, i=i+1);
|
||||
|
||||
|
||||
// Function: min_index()
|
||||
|
@ -425,7 +451,7 @@ function range(n, s=0, e, step) =
|
|||
let( step = (n!=undef && e!=undef)? (e-s)/(n-1) : default(step,1) )
|
||||
is_undef(e)
|
||||
? assert( is_consistent([s, step]), "Incompatible data.")
|
||||
[for (i=[0:1:n-1]) s+step*i ]
|
||||
[for (i=[0:1:n-1]) s+step*i]
|
||||
: assert( is_vector([s,step,e]), "Start `s`, step `step` and end `e` must be numbers.")
|
||||
[for (v=[s:step:e]) v] ;
|
||||
|
||||
|
@ -468,10 +494,10 @@ function rangex(n, s=0, e, step) =
|
|||
let( step = (n!=undef && e!=undef)? (e-s)/n : default(step,1) )
|
||||
is_undef(e)
|
||||
? assert( is_consistent([s, step]), "Incompatible data.")
|
||||
[for (i=[0:1:n-1]) s+step*i ]
|
||||
[for (i=[0:1:n-1]) s+step*i]
|
||||
: assert( is_vector([s,step,e]), "Start `s`, step `step` and end `e` must be numbers.")
|
||||
let(steps=floor((e-s)/step+0.5))
|
||||
[for (i=[0:1:steps-1]) s+step*i ];
|
||||
[for (i=[0:1:steps-1]) s+step*i];
|
||||
|
||||
|
||||
|
||||
|
|
13
common.scad
13
common.scad
|
@ -185,6 +185,19 @@ function valid_range(x) =
|
|||
: ( x[1]<0 && x[0]>=x[2] ) );
|
||||
|
||||
|
||||
// Function: is_func()
|
||||
// Usage:
|
||||
// bool = is_func(x);
|
||||
// Description:
|
||||
// Returns true if OpenSCAD supports function literals, and the given item is one.
|
||||
// Arguments:
|
||||
// x = The value to check against.
|
||||
// Example:
|
||||
// f = function (a) a==2;
|
||||
// bool = is_func(f); // Returns: true
|
||||
function is_func(x) = version_num()>20210000 && is_function(x);
|
||||
|
||||
|
||||
// Function: is_consistent()
|
||||
// Usage:
|
||||
// bool = is_consistent(list, <pattern>);
|
||||
|
|
|
@ -40,24 +40,30 @@ module move_copies(a=[[0,0,0]])
|
|||
}
|
||||
|
||||
|
||||
// Module: line_of()
|
||||
// Function&Module: line_of()
|
||||
//
|
||||
// Usage: Spread `n` copies by a given spacing
|
||||
// line_of(spacing, [n], [p1]) ...
|
||||
// line_of(spacing, <n>, <p1=>) ...
|
||||
// Usage: Spread copies every given spacing along the line
|
||||
// line_of(spacing, l, [p1]) ...
|
||||
// line_of(spacing, <l=>, <p1=>) ...
|
||||
// Usage: Spread `n` copies along the length of the line
|
||||
// line_of(l, [n], [p1]) ...
|
||||
// line_of(<n=>, <l=>, <p1=>) ...
|
||||
// Usage: Spread `n` copies along the line from `p1` to `p2`
|
||||
// line_of(p1, p2, [n]) ...
|
||||
// line_of(<n=>, <p1=>, <p2=>) ...
|
||||
// Usage: Spread copies every given spacing, centered along the line from `p1` to `p2`
|
||||
// line_of(p1, p2, spacing) ...
|
||||
//
|
||||
// line_of(<spacing>, <p1=>, <p2=>) ...
|
||||
// Usage: As a function
|
||||
// pts = line_of(<spacing>, <n>, <p1=>);
|
||||
// pts = line_of(<spacing>, <l=>, <p1=>);
|
||||
// pts = line_of(<n=>, <l=>, <p1=>);
|
||||
// pts = line_of(<n=>, <p1=>, <p2=>);
|
||||
// pts = line_of(<spacing>, <p1=>, <p2=>);
|
||||
// Description:
|
||||
// Copies `children()` at one or more evenly spread positions along a line. By default, the line
|
||||
// will be centered at the origin, unless the starting point `p1` is given. The line will be
|
||||
// pointed towards `RIGHT` (X+) unless otherwise given as a vector in `l`, `spacing`, or `p1`/`p2`.
|
||||
// The spread is specified in one of several ways:
|
||||
// When called as a function, returns a list of points at evenly spread positions along a line.
|
||||
// When called as a module, copies `children()` at one or more evenly spread positions along a line.
|
||||
// By default, the line will be centered at the origin, unless the starting point `p1` is given.
|
||||
// The line will be pointed towards `RIGHT` (X+) unless otherwise given as a vector in `l`,
|
||||
// `spacing`, or `p1`/`p2`. The spread is specified in one of several ways:
|
||||
// .
|
||||
// If You Know... | Then Use Something Like...
|
||||
// -------------------------------- | --------------------------------
|
||||
|
@ -74,6 +80,7 @@ module move_copies(a=[[0,0,0]])
|
|||
// Arguments:
|
||||
// spacing = Either the scalar spacing distance along the X+ direction, or the vector giving both the direction and spacing distance between each set of copies.
|
||||
// n = Number of copies to distribute along the line. (Default: 2)
|
||||
// ---
|
||||
// l = Either the scalar length of the line, or a vector giving both the direction and length of the line.
|
||||
// p1 = If given, specifies the starting point of the line.
|
||||
// p2 = If given with `p1`, specifies the ending point of line, and indirectly calculates the line length.
|
||||
|
@ -102,40 +109,42 @@ module move_copies(a=[[0,0,0]])
|
|||
// cube(size=[1,3,1],center=true);
|
||||
// cube(size=[3,1,1],center=true);
|
||||
// }
|
||||
// Example(2D):
|
||||
// pts = line_of([10,5],n=5);
|
||||
// move_copies(pts) circle(d=2);
|
||||
module line_of(spacing, n, l, p1, p2)
|
||||
{
|
||||
assert(is_undef(spacing) || is_finite(spacing) || is_vector(spacing));
|
||||
assert(is_undef(n) || is_finite(n));
|
||||
assert(is_undef(l) || is_finite(l) || is_vector(l));
|
||||
assert(is_undef(p1) || is_vector(p1));
|
||||
assert(is_undef(p2) || is_vector(p2));
|
||||
ll = (
|
||||
!is_undef(l)? scalar_vec3(l, 0) :
|
||||
(!is_undef(spacing) && !is_undef(n))? (n * scalar_vec3(spacing, 0)) :
|
||||
(!is_undef(p1) && !is_undef(p2))? point3d(p2-p1) :
|
||||
undef
|
||||
);
|
||||
cnt = (
|
||||
!is_undef(n)? n :
|
||||
(!is_undef(spacing) && !is_undef(ll))? floor(norm(ll) / norm(scalar_vec3(spacing, 0)) + 1.000001) :
|
||||
2
|
||||
);
|
||||
spc = (
|
||||
cnt<=1? [0,0,0] :
|
||||
is_undef(spacing)? (ll/(cnt-1)) :
|
||||
is_num(spacing) && !is_undef(ll)? (ll/(cnt-1)) :
|
||||
scalar_vec3(spacing, 0)
|
||||
);
|
||||
assert(!is_undef(cnt), "Need two of `spacing`, 'l', 'n', or `p1`/`p2` arguments in `line_of()`.");
|
||||
spos = !is_undef(p1)? point3d(p1) : -(cnt-1)/2 * spc;
|
||||
for (i=[0:1:cnt-1]) {
|
||||
pos = i * spc + spos;
|
||||
$pos = pos;
|
||||
pts = line_of(spacing=spacing, n=n, l=l, p1=p1, p2=p2);
|
||||
for (i=idx(pts)) {
|
||||
$idx = i;
|
||||
translate(pos) children();
|
||||
$pos = pts[i];
|
||||
translate($pos) children();
|
||||
}
|
||||
}
|
||||
|
||||
function line_of(spacing, n, l, p1, p2) =
|
||||
assert(is_undef(spacing) || is_finite(spacing) || is_vector(spacing))
|
||||
assert(is_undef(n) || is_finite(n))
|
||||
assert(is_undef(l) || is_finite(l) || is_vector(l))
|
||||
assert(is_undef(p1) || is_vector(p1))
|
||||
assert(is_undef(p2) || is_vector(p2))
|
||||
let(
|
||||
ll = !is_undef(l)? scalar_vec3(l, 0) :
|
||||
(!is_undef(spacing) && !is_undef(n))? (n * scalar_vec3(spacing, 0)) :
|
||||
(!is_undef(p1) && !is_undef(p2))? point3d(p2-p1) :
|
||||
undef,
|
||||
cnt = !is_undef(n)? n :
|
||||
(!is_undef(spacing) && !is_undef(ll))? floor(norm(ll) / norm(scalar_vec3(spacing, 0)) + 1.000001) :
|
||||
2,
|
||||
spc = cnt<=1? [0,0,0] :
|
||||
is_undef(spacing)? (ll/(cnt-1)) :
|
||||
is_num(spacing) && !is_undef(ll)? (ll/(cnt-1)) :
|
||||
scalar_vec3(spacing, 0)
|
||||
)
|
||||
assert(!is_undef(cnt), "Need two of `spacing`, 'l', 'n', or `p1`/`p2` arguments in `line_of()`.")
|
||||
let( spos = !is_undef(p1)? point3d(p1) : -(cnt-1)/2 * spc )
|
||||
[for (i=[0:1:cnt-1]) i * spc + spos];
|
||||
|
||||
|
||||
// Module: xcopies()
|
||||
//
|
||||
|
|
168
math.scad
168
math.scad
|
@ -174,6 +174,31 @@ function lerp(a,b,u) =
|
|||
[for (v = u) (1-v)*a + v*b ];
|
||||
|
||||
|
||||
// Function: lerpn()
|
||||
// Usage:
|
||||
// x = lerpn(a, b, n);
|
||||
// x = lerpn(a, b, n, <endpoint>);
|
||||
// Description:
|
||||
// Returns exactly `n` values, linearly interpolated between `a` and `b`.
|
||||
// If `endpoint` is true, then the last value will exactly equal `b`.
|
||||
// If `endpoint` is false, then the last value will about `a+(b-a)*(1-1/n)`.
|
||||
// Arguments:
|
||||
// a = First value or vector.
|
||||
// b = Second value or vector.
|
||||
// n = The number of values to return.
|
||||
// endpoint = If true, the last value will be exactly `b`. If false, the last value will be one step less.
|
||||
// Examples:
|
||||
// l = lerpn(-4,4,9); // Returns: [-4,-3,-2,-1,0,1,2,3,4]
|
||||
// l = lerpn(-4,4,8,false); // Returns: [-4,-3,-2,-1,0,1,2,3]
|
||||
// l = lerpn(0,1,6); // Returns: [0, 0.2, 0.4, 0.6, 0.8, 1]
|
||||
// l = lerpn(0,1,5,false); // Returns: [0, 0.2, 0.4, 0.6, 0.8]
|
||||
function lerpn(a,b,n,endpoint=true) =
|
||||
assert(same_shape(a,b), "Bad or inconsistent inputs to lerp")
|
||||
assert(is_int(n))
|
||||
assert(is_bool(endpoint))
|
||||
let( d = n - (endpoint? 1 : 0) )
|
||||
[for (i=[0:1:n-1]) let(u=i/d) (1-u)*a + u*b];
|
||||
|
||||
|
||||
// Section: Undef Safe Math
|
||||
|
||||
|
@ -434,32 +459,6 @@ function modang(x) =
|
|||
let(xx = posmod(x,360)) xx<180? xx : xx-360;
|
||||
|
||||
|
||||
// Function: modrange()
|
||||
// Usage:
|
||||
// modrange(x, y, m, <step>)
|
||||
// Description:
|
||||
// Returns a normalized list of numbers from `x` to `y`, by `step`, modulo `m`. Wraps if `x` > `y`.
|
||||
// Arguments:
|
||||
// x = The start value to constrain.
|
||||
// y = The end value to constrain.
|
||||
// m = Modulo value.
|
||||
// step = Step by this amount.
|
||||
// Examples:
|
||||
// modrange(90,270,360, step=45); // Returns: [90,135,180,225,270]
|
||||
// modrange(270,90,360, step=45); // Returns: [270,315,0,45,90]
|
||||
// modrange(90,270,360, step=-45); // Returns: [90,45,0,315,270]
|
||||
// modrange(270,90,360, step=-45); // Returns: [270,225,180,135,90]
|
||||
function modrange(x, y, m, step=1) =
|
||||
assert( is_finite(x+y+step+m) && !approx(m,0), "Input must be finite numbers and the module value cannot be zero." )
|
||||
let(
|
||||
a = posmod(x, m),
|
||||
b = posmod(y, m),
|
||||
c = step>0? (a>b? b+m : b)
|
||||
: (a<b? b-m : b)
|
||||
) [for (i=[a:step:c]) (i%m+m)%m ];
|
||||
|
||||
|
||||
|
||||
// Section: Random Number Generation
|
||||
|
||||
// Function: rand_int()
|
||||
|
@ -1216,72 +1215,85 @@ function compare_vals(a, b) =
|
|||
// a = First list to compare.
|
||||
// b = Second list to compare.
|
||||
function compare_lists(a, b) =
|
||||
a==b? 0
|
||||
: let(
|
||||
cmps = [ for(i=[0:1:min(len(a),len(b))-1])
|
||||
let( cmp = compare_vals(a[i],b[i]) )
|
||||
if(cmp!=0) cmp
|
||||
]
|
||||
)
|
||||
cmps==[]? (len(a)-len(b)) : cmps[0];
|
||||
a==b? 0 :
|
||||
let(
|
||||
cmps = [
|
||||
for (i = [0:1:min(len(a),len(b))-1])
|
||||
let( cmp = compare_vals(a[i],b[i]) )
|
||||
if (cmp!=0) cmp
|
||||
]
|
||||
)
|
||||
cmps==[]? (len(a)-len(b)) : cmps[0];
|
||||
|
||||
|
||||
// Function: any()
|
||||
// Usage:
|
||||
// b = any(l);
|
||||
// b = any(l,func);
|
||||
// Description:
|
||||
// Returns true if any item in list `l` evaluates as true.
|
||||
// If `l` is a lists of lists, `any()` is applied recursively to each sublist.
|
||||
// Arguments:
|
||||
// l = The list to test for true items.
|
||||
// func = An optional function literal of signature (x), returning bool, to test each list item with.
|
||||
// Example:
|
||||
// any([0,false,undef]); // Returns false.
|
||||
// any([1,false,undef]); // Returns true.
|
||||
// any([1,5,true]); // Returns true.
|
||||
// any([[0,0], [0,0]]); // Returns false.
|
||||
// any([[0,0], [0,0]]); // Returns true.
|
||||
// any([[0,0], [1,0]]); // Returns true.
|
||||
function any(l) =
|
||||
function any(l, func) =
|
||||
assert(is_list(l), "The input is not a list." )
|
||||
_any(l);
|
||||
assert(func==undef || is_func(func))
|
||||
is_func(func)
|
||||
? _any_func(l, func)
|
||||
: _any_bool(l);
|
||||
|
||||
function _any(l, i=0, succ=false) =
|
||||
(i>=len(l) || succ)? succ :
|
||||
_any(
|
||||
l, i+1,
|
||||
succ = is_list(l[i]) ? _any(l[i]) : !(!l[i])
|
||||
);
|
||||
function _any_func(l, func, i=0, out=false) =
|
||||
i >= len(l) || out? out :
|
||||
_any_func(l, func, i=i+1, out=out || func(l[i]));
|
||||
|
||||
function _any_bool(l, i=0, out=false) =
|
||||
i >= len(l) || out? out :
|
||||
_any_bool(l, i=i+1, out=out || l[i]);
|
||||
|
||||
|
||||
// Function: all()
|
||||
// Usage:
|
||||
// b = all(l);
|
||||
// b = all(l,func);
|
||||
// Description:
|
||||
// Returns true if all items in list `l` evaluate as true.
|
||||
// If `l` is a lists of lists, `all()` is applied recursively to each sublist.
|
||||
// Returns true if all items in list `l` evaluate as true. If `func` is given a function liteal
|
||||
// of signature (x), returning bool, then that function literal is evaluated for each list item.
|
||||
// Arguments:
|
||||
// l = The list to test for true items.
|
||||
// func = An optional function literal of signature (x), returning bool, to test each list item with.
|
||||
// Example:
|
||||
// all([0,false,undef]); // Returns false.
|
||||
// all([1,false,undef]); // Returns false.
|
||||
// all([1,5,true]); // Returns true.
|
||||
// all([[0,0], [0,0]]); // Returns false.
|
||||
// all([[0,0], [1,0]]); // Returns false.
|
||||
// all([[0,0], [0,0]]); // Returns true.
|
||||
// all([[0,0], [1,0]]); // Returns true.
|
||||
// all([[1,1], [1,1]]); // Returns true.
|
||||
function all(l) =
|
||||
assert( is_list(l), "The input is not a list." )
|
||||
_all(l);
|
||||
function all(l, func) =
|
||||
assert(is_list(l), "The input is not a list.")
|
||||
assert(func==undef || is_func(func))
|
||||
is_func(func)
|
||||
? _all_func(l, func)
|
||||
: _all_bool(l);
|
||||
|
||||
function _all(l, i=0, fail=false) =
|
||||
(i>=len(l) || fail)? !fail :
|
||||
_all(
|
||||
l, i+1,
|
||||
fail = is_list(l[i]) ? !_all(l[i]) : !l[i]
|
||||
) ;
|
||||
function _all_func(l, func, i=0, out=true) =
|
||||
i >= len(l) || !out? out :
|
||||
_all_func(l, func, i=i+1, out=out && func(l[i]));
|
||||
|
||||
function _all_bool(l, i=0, out=true) =
|
||||
i >= len(l) || !out? out :
|
||||
_all_bool(l, i=i+1, out=out && l[i]);
|
||||
|
||||
|
||||
// Function: count_true()
|
||||
// Usage:
|
||||
// n = count_true(l)
|
||||
// n = count_true(l,<nmax=>)
|
||||
// n = count_true(l,func,<nmax=>)
|
||||
// Description:
|
||||
// Returns the number of items in `l` that evaluate as true.
|
||||
// If `l` is a lists of lists, this is applied recursively to each
|
||||
|
@ -1289,24 +1301,38 @@ function _all(l, i=0, fail=false) =
|
|||
// in all recursive sublists.
|
||||
// Arguments:
|
||||
// l = The list to test for true items.
|
||||
// nmax = If given, stop counting if `nmax` items evaluate as true.
|
||||
// func = An optional function literal of signature (x), returning bool, to test each list item with.
|
||||
// ---
|
||||
// nmax = Max number of true items to count. Default: `undef` (no limit)
|
||||
// Example:
|
||||
// count_true([0,false,undef]); // Returns 0.
|
||||
// count_true([1,false,undef]); // Returns 1.
|
||||
// count_true([1,5,false]); // Returns 2.
|
||||
// count_true([1,5,true]); // Returns 3.
|
||||
// count_true([[0,0], [0,0]]); // Returns 0.
|
||||
// count_true([[0,0], [1,0]]); // Returns 1.
|
||||
// count_true([[1,1], [1,1]]); // Returns 4.
|
||||
// count_true([[1,1], [1,1]], nmax=3); // Returns 3.
|
||||
function _count_true_rec(l, nmax, _cnt=0, _i=0) =
|
||||
_i>=len(l) || (is_num(nmax) && _cnt>=nmax)? _cnt :
|
||||
_count_true_rec(l, nmax, _cnt=_cnt+(l[_i]?1:0), _i=_i+1);
|
||||
// count_true([[0,0], [0,0]]); // Returns 2.
|
||||
// count_true([[0,0], [1,0]]); // Returns 2.
|
||||
// count_true([[1,1], [1,1]]); // Returns 2.
|
||||
// count_true([[1,1], [1,1]], nmax=1); // Returns 1.
|
||||
function count_true(l, func, nmax) =
|
||||
assert(is_list(l))
|
||||
assert(func==undef || is_func(func))
|
||||
is_func(func)
|
||||
? _count_true_func(l, func, nmax)
|
||||
: _count_true_bool(l, nmax);
|
||||
|
||||
function count_true(l, nmax) =
|
||||
is_undef(nmax)? len([for (x=l) if(x) 1]) :
|
||||
!is_list(l) ? ( l? 1: 0) :
|
||||
_count_true_rec(l, nmax);
|
||||
function _count_true_func(l, func, nmax, i=0, out=0) =
|
||||
i >= len(l) || (nmax!=undef && out>=nmax) ? out :
|
||||
_count_true_func(
|
||||
l, func, nmax, i = i + 1,
|
||||
out = out + (func(l[i])? 1:0)
|
||||
);
|
||||
|
||||
function _count_true_bool(l, nmax, i=0, out=0) =
|
||||
i >= len(l) || (nmax!=undef && out>=nmax) ? out :
|
||||
_count_true_bool(
|
||||
l, nmax, i = i + 1,
|
||||
out = out + (l[i]? 1:0)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
@ -1573,6 +1599,7 @@ function c_ident(n) = [for (i = [0:1:n-1]) [for (j = [0:1:n-1]) (i==j)?[1,0]:[0,
|
|||
function c_norm(z) = norm_fro(z);
|
||||
|
||||
|
||||
|
||||
// Section: Polynomials
|
||||
|
||||
// Function: quadratic_roots()
|
||||
|
@ -1624,6 +1651,7 @@ function polynomial(p,z,k,total) =
|
|||
: k==len(p) ? total
|
||||
: polynomial(p,z,k+1, is_num(z) ? total*z+p[k] : c_mul(total,z)+[p[k],0]);
|
||||
|
||||
|
||||
// Function: poly_mult()
|
||||
// Usage:
|
||||
// x = polymult(p,q)
|
||||
|
|
|
@ -299,15 +299,6 @@ module test_modang() {
|
|||
test_modang();
|
||||
|
||||
|
||||
module test_modrange() {
|
||||
assert_equal(modrange(-5,5,3), [1,2]);
|
||||
assert_equal(modrange(-1,4,3), [2,0,1]);
|
||||
assert_equal(modrange(1,8,10,step=2), [1,3,5,7]);
|
||||
assert_equal(modrange(5,12,10,step=2), [5,7,9,1]);
|
||||
}
|
||||
test_modrange();
|
||||
|
||||
|
||||
module test_sqr() {
|
||||
assert_equal(sqr(-3), 9);
|
||||
assert_equal(sqr(0), 0);
|
||||
|
@ -738,11 +729,14 @@ module test_any() {
|
|||
assert_equal(any([0,false,undef]), false);
|
||||
assert_equal(any([1,false,undef]), true);
|
||||
assert_equal(any([1,5,true]), true);
|
||||
assert_equal(any([[0,0], [0,0]]), false);
|
||||
assert_equal(any([[0,0], [0,0]]), true);
|
||||
assert_equal(any([[0,0], [1,0]]), true);
|
||||
assert_equal(any([[false,false],[[false,[false],[[[true]]]],false],[false,false]]), true);
|
||||
assert_equal(any([[false,false],[[false,[false],[[[false]]]],false],[false,false]]), false);
|
||||
assert_equal(any([[false,false],[[false,[false],[[[false]]]],false],[false,false]]), true);
|
||||
assert_equal(any([]), false);
|
||||
assert_equal(any([1,3,5,7,9], function (a) a%2==0),false);
|
||||
assert_equal(any([1,3,6,7,9], function (a) a%2==0),true);
|
||||
assert_equal(any([1,3,5,7,9], function (a) a%2!=0),true);
|
||||
}
|
||||
test_any();
|
||||
|
||||
|
@ -751,12 +745,15 @@ module test_all() {
|
|||
assert_equal(all([0,false,undef]), false);
|
||||
assert_equal(all([1,false,undef]), false);
|
||||
assert_equal(all([1,5,true]), true);
|
||||
assert_equal(all([[0,0], [0,0]]), false);
|
||||
assert_equal(all([[0,0], [1,0]]), false);
|
||||
assert_equal(all([[0,0], [0,0]]), true);
|
||||
assert_equal(all([[0,0], [1,0]]), true);
|
||||
assert_equal(all([[1,1], [1,1]]), true);
|
||||
assert_equal(all([[true,true],[[true,[true],[[[true]]]],true],[true,true]]), true);
|
||||
assert_equal(all([[true,true],[[true,[true],[[[false]]]],true],[true,true]]), false);
|
||||
assert_equal(all([[true,true],[[true,[true],[[[true]]]],true],[true,true]]), true);
|
||||
assert_equal(all([[true,true],[[true,[true],[[[false]]]],true],[true,true]]), true);
|
||||
assert_equal(all([]), true);
|
||||
assert_equal(all([1,3,5,7,9], function (a) a%2==0),false);
|
||||
assert_equal(all([1,3,6,8,9], function (a) a%2==0),false);
|
||||
assert_equal(all([1,3,5,7,9], function (a) a%2!=0),true);
|
||||
}
|
||||
test_all();
|
||||
|
||||
|
@ -770,6 +767,9 @@ module test_count_true() {
|
|||
assert_equal(count_true([[0,0], [1,0]]), 2);
|
||||
assert_equal(count_true([[1,1], [1,1]]), 2);
|
||||
assert_equal(count_true([1,1,1,1,1], nmax=3), 3);
|
||||
assert_equal(count_true([1,3,5,7,9], function (a) a%2==0),0);
|
||||
assert_equal(count_true([1,3,6,8,9], function (a) a%2==0),2);
|
||||
assert_equal(count_true([1,3,5,7,9], function (a) a%2!=0),5);
|
||||
}
|
||||
test_count_true();
|
||||
|
||||
|
@ -789,6 +789,7 @@ module test_factorial() {
|
|||
}
|
||||
test_factorial();
|
||||
|
||||
|
||||
module test_binomial() {
|
||||
assert_equal(binomial(1), [1,1]);
|
||||
assert_equal(binomial(2), [1,2,1]);
|
||||
|
@ -797,6 +798,7 @@ module test_binomial() {
|
|||
}
|
||||
test_binomial();
|
||||
|
||||
|
||||
module test_binomial_coefficient() {
|
||||
assert_equal(binomial_coefficient(2,1), 2);
|
||||
assert_equal(binomial_coefficient(3,2), 3);
|
||||
|
@ -815,8 +817,8 @@ module test_gcd() {
|
|||
assert_equal(gcd(39, 101),1);
|
||||
assert_equal(gcd(15,-25), 5);
|
||||
assert_equal(gcd(-15,25), 5);
|
||||
assert_equal(gcd(5,0),5);
|
||||
assert_equal(gcd(0,5),5);
|
||||
assert_equal(gcd(5,0), 5);
|
||||
assert_equal(gcd(0,5), 5);
|
||||
}
|
||||
test_gcd();
|
||||
|
||||
|
|
Loading…
Reference in a new issue