mirror of
https://github.com/JustinSDK/dotSCAD.git
synced 2025-02-06 08:08:32 +01:00
add bsearch
This commit is contained in:
parent
f78ac97b40
commit
4d63ad44bb
@ -1,25 +0,0 @@
|
|||||||
# bsearch
|
|
||||||
|
|
||||||
The `bsearch` function is a general-purpose function to find a value or a list of values in a vector. The vector must be sorted by zyx (from the last index to the first one).
|
|
||||||
|
|
||||||
**Since:** 2.3
|
|
||||||
|
|
||||||
## Parameters
|
|
||||||
|
|
||||||
- `sorted` : The sorted vector.
|
|
||||||
- `elem` : a list of values.
|
|
||||||
- `by` : Can be `"x"`、`"y"`、`"z"`, `"idx"` (Default) or `"vt"`.
|
|
||||||
- `idx` : When `by` is `"idx"`, the value of `idx` is used. The Default value is 0.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
use <util/sort.scad>;
|
|
||||||
use <util/bsearch.scad>;
|
|
||||||
|
|
||||||
points = [[1, 1], [3, 4], [7, 2], [5, 2]];
|
|
||||||
sorted = sort(points, by = "vt");
|
|
||||||
|
|
||||||
echo(sorted); // [[1, 1], [5, 2], [7, 2], [3, 4]]
|
|
||||||
assert(bsearch(sorted, [5, 4], by = "x") == 1);
|
|
||||||
assert(bsearch(sorted, [5, 4], by = "y") == 3);
|
|
||||||
assert(bsearch(sorted, [7, 2], by = "vt") == 2);
|
|
26
docs/lib3x-bsearch.md
Normal file
26
docs/lib3x-bsearch.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# bsearch
|
||||||
|
|
||||||
|
The `bsearch` function is a general-purpose function to search a value in a list whose elements must be sorted by zyx (from the last index to the first one).
|
||||||
|
|
||||||
|
**Since:** 3.0
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
- `sorted` : The sorted list.
|
||||||
|
- `target` : The target vector or a function literal.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
use <util/sort.scad>;
|
||||||
|
use <util/bsearch.scad>;
|
||||||
|
|
||||||
|
points = [[1, 1], [3, 4], [7, 2], [5, 2]];
|
||||||
|
sorted = sort(points, by = "vt"); // [[1, 1], [5, 2], [7, 2], [3, 4]]
|
||||||
|
|
||||||
|
assert(bsearch(sorted, [7, 2]) == 2);
|
||||||
|
|
||||||
|
xIs5 = function(elem) elem[0] - 5;
|
||||||
|
assert(bsearch(sorted, xIs5) == 1);
|
||||||
|
|
||||||
|
yIs4 = function(elem) elem[1] - 4;
|
||||||
|
assert(bsearch(sorted, yIs4) == 3);
|
@ -1,20 +1,13 @@
|
|||||||
use <_vt_default_comparator.scad>;
|
use <_vt_default_comparator.scad>;
|
||||||
|
|
||||||
function _binary_search_by(sorted, elem, low, upper, i) =
|
|
||||||
low > upper ? -1 :
|
|
||||||
let(mid = floor((low + upper) / 2))
|
|
||||||
sorted[mid][i] < elem[i] ? _binary_search_by(sorted, elem, mid + 1, upper, i) :
|
|
||||||
sorted[mid][i] > elem[i] ? _binary_search_by(sorted, elem, low, mid - 1, i) : mid;
|
|
||||||
|
|
||||||
function _bsearch_vt(sorted, elem, low, upper) =
|
function _bsearch_vt(sorted, elem, low, upper) =
|
||||||
low > upper ? -1 :
|
low > upper ? -1 :
|
||||||
let(mid = floor((low + upper) / 2))
|
let(mid = floor((low + upper) / 2))
|
||||||
lessThan(sorted[mid], elem) ? _bsearch_vt(sorted, elem, mid + 1, upper) :
|
lessThan(sorted[mid], elem) ? _bsearch_vt(sorted, elem, mid + 1, upper) :
|
||||||
greaterThan(sorted[mid], elem) ? _bsearch_vt(sorted, elem, low, mid - 1) : mid;
|
greaterThan(sorted[mid], elem) ? _bsearch_vt(sorted, elem, low, mid - 1) : mid;
|
||||||
|
|
||||||
function _bsearch_by(sorted, elem, by, idx) =
|
function _bsearch_cmp(sorted, cmp, low, upper) =
|
||||||
let(
|
low > upper ? -1 :
|
||||||
dict = [["x", 0], ["y", 1], ["z", 2], ["i", idx]],
|
let(mid = floor((low + upper) / 2))
|
||||||
i = dict[search(by == "idx" ? "i" : by, dict)[0]][1]
|
cmp(sorted[mid]) < 0 ? _bsearch_cmp(sorted, cmp, mid + 1, upper) :
|
||||||
)
|
cmp(sorted[mid]) > 0 ? _bsearch_cmp(sorted, cmp, low, mid - 1) : mid;
|
||||||
_binary_search_by(sorted, elem, 0, len(sorted) - 1, i);
|
|
@ -4,12 +4,12 @@
|
|||||||
* @copyright Justin Lin, 2020
|
* @copyright Justin Lin, 2020
|
||||||
* @license https://opensource.org/licenses/lgpl-3.0.html
|
* @license https://opensource.org/licenses/lgpl-3.0.html
|
||||||
*
|
*
|
||||||
* @see https://openhome.cc/eGossip/OpenSCAD/lib2x-bsearch.html
|
* @see https://openhome.cc/eGossip/OpenSCAD/lib3x-bsearch.html
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
use <_impl/_bsearch_impl.scad>;
|
use <_impl/_bsearch_impl.scad>;
|
||||||
|
|
||||||
function bsearch(sorted, elem, by = "idx", idx = 0) =
|
function bsearch(sorted, target) =
|
||||||
by == "vt" ? _bsearch_vt(sorted, elem, 0, len(sorted) - 1) : // for example, `sorted` is by zyx
|
is_function(target) ? _bsearch_cmp(sorted, target, 0, len(sorted) - 1) :
|
||||||
_bsearch_by(sorted, elem, by, idx);
|
_bsearch_vt(sorted, target, 0, len(sorted) - 1); // `sorted` is by zyx
|
19
test/util/test_bsearch.scad
Normal file
19
test/util/test_bsearch.scad
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use <util/sort.scad>;
|
||||||
|
use <util/bsearch.scad>;
|
||||||
|
|
||||||
|
module test_bsearch() {
|
||||||
|
echo("==== test_bsearch ====");
|
||||||
|
|
||||||
|
points = [[1, 1], [3, 4], [7, 2], [5, 2]];
|
||||||
|
sorted = sort(points, by = "vt"); // [[1, 1], [5, 2], [7, 2], [3, 4]]
|
||||||
|
|
||||||
|
assert(bsearch(sorted, [7, 2]) == 2);
|
||||||
|
|
||||||
|
xIs5 = function(elem) elem[0] - 5;
|
||||||
|
assert(bsearch(sorted, xIs5) == 1);
|
||||||
|
|
||||||
|
yIs4 = function(elem) elem[1] - 4;
|
||||||
|
assert(bsearch(sorted, yIs4) == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_bsearch();
|
Loading…
x
Reference in New Issue
Block a user