@thi.ng/arrays 2.4.7 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -1
- package/README.md +2 -1
- package/floyd-rivest.d.ts +30 -0
- package/floyd-rivest.js +69 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2022-12-
|
|
3
|
+
- **Last updated**: 2022-12-29T20:56:59Z
|
|
4
4
|
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file.
|
|
@@ -9,6 +9,12 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
|
|
|
9
9
|
**Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
|
|
10
10
|
and/or version bumps of transitive dependencies.
|
|
11
11
|
|
|
12
|
+
## [2.5.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/arrays@2.5.0) (2022-12-29)
|
|
13
|
+
|
|
14
|
+
#### 🚀 Features
|
|
15
|
+
|
|
16
|
+
- add Floyd-Rivest impl, update readme ([7773d59](https://github.com/thi-ng/umbrella/commit/7773d59))
|
|
17
|
+
|
|
12
18
|
## [2.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/arrays@2.4.0) (2022-10-31)
|
|
13
19
|
|
|
14
20
|
#### 🚀 Features
|
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ For Node.js REPL:
|
|
|
48
48
|
const arrays = await import("@thi.ng/arrays");
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
Package sizes (brotli'd, pre-treeshake): ESM: 2.
|
|
51
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 2.61 KB
|
|
52
52
|
|
|
53
53
|
## Dependencies
|
|
54
54
|
|
|
@@ -73,6 +73,7 @@ Package sizes (brotli'd, pre-treeshake): ESM: 2.40 KB
|
|
|
73
73
|
- [ensureIterable()](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays/src/ensure-iterable.ts)
|
|
74
74
|
- [fillRange()](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays/src/fill-range.ts)
|
|
75
75
|
- [find()](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays/src/find.ts)
|
|
76
|
+
- [floydRivest()](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays/src/floyd-rivest.ts)
|
|
76
77
|
- [fuzzyMatch()](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays/src/fuzzy-match.ts)
|
|
77
78
|
- [insert()](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays/src/insert.ts)
|
|
78
79
|
- [into()](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays/src/into.ts)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Comparator } from "@thi.ng/api";
|
|
2
|
+
/**
|
|
3
|
+
* Implementation of the Floyd-Rivest selection algorithm to partially find &
|
|
4
|
+
* sort the `k`th smallest elements in given array, according to supplied
|
|
5
|
+
* comparator.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* `k` is the desired index value, where `buf[k]` is the `(k+1)`th smallest
|
|
9
|
+
* element when `left=0` (default).
|
|
10
|
+
*
|
|
11
|
+
* **IMPORTANT:** Mutates (partially sorts) given array such that all items in
|
|
12
|
+
* the `[left, k]` interval are the smallest.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* floydRivest([5, 3, -1, -10, 20, 7, 0, 4, 2], 3);
|
|
17
|
+
* // [ -10, 0, -1, 2, 3, 4, 5, 20, 7 ]
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* Based on pseudo-code from:
|
|
21
|
+
* - https://en.wikipedia.org/wiki/Floyd%E2%80%93Rivest_algorithm
|
|
22
|
+
*
|
|
23
|
+
* @param buf
|
|
24
|
+
* @param k
|
|
25
|
+
* @param cmp
|
|
26
|
+
* @param left
|
|
27
|
+
* @param right
|
|
28
|
+
*/
|
|
29
|
+
export declare const floydRivest: <T>(buf: T[], k?: number, cmp?: Comparator<T>, left?: number, right?: number) => T[];
|
|
30
|
+
//# sourceMappingURL=floyd-rivest.d.ts.map
|
package/floyd-rivest.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { compare } from "@thi.ng/compare/compare";
|
|
2
|
+
import { swap } from "./swap.js";
|
|
3
|
+
/**
|
|
4
|
+
* Implementation of the Floyd-Rivest selection algorithm to partially find &
|
|
5
|
+
* sort the `k`th smallest elements in given array, according to supplied
|
|
6
|
+
* comparator.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* `k` is the desired index value, where `buf[k]` is the `(k+1)`th smallest
|
|
10
|
+
* element when `left=0` (default).
|
|
11
|
+
*
|
|
12
|
+
* **IMPORTANT:** Mutates (partially sorts) given array such that all items in
|
|
13
|
+
* the `[left, k]` interval are the smallest.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* floydRivest([5, 3, -1, -10, 20, 7, 0, 4, 2], 3);
|
|
18
|
+
* // [ -10, 0, -1, 2, 3, 4, 5, 20, 7 ]
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Based on pseudo-code from:
|
|
22
|
+
* - https://en.wikipedia.org/wiki/Floyd%E2%80%93Rivest_algorithm
|
|
23
|
+
*
|
|
24
|
+
* @param buf
|
|
25
|
+
* @param k
|
|
26
|
+
* @param cmp
|
|
27
|
+
* @param left
|
|
28
|
+
* @param right
|
|
29
|
+
*/
|
|
30
|
+
export const floydRivest = (buf, k = 1, cmp = compare, left = 0, right = buf.length - 1) => {
|
|
31
|
+
while (right > left) {
|
|
32
|
+
// constants 600 & 0.5 are from original paper
|
|
33
|
+
if (right - left > 600) {
|
|
34
|
+
const n = right - left + 1;
|
|
35
|
+
const i = k - left + 1;
|
|
36
|
+
const z = Math.log(n);
|
|
37
|
+
const s = 0.5 * Math.exp(z * (2 / 3));
|
|
38
|
+
const sd = 0.5 * Math.sqrt(z * s * ((n - s) / n)) * Math.sign(i - n / 2);
|
|
39
|
+
floydRivest(buf, k, cmp, Math.max(left, (k - (i * s) / n + sd) | 0), Math.min(right, (k + ((n - i) * s) / n + sd) | 0));
|
|
40
|
+
}
|
|
41
|
+
const t = buf[k];
|
|
42
|
+
let i = left;
|
|
43
|
+
let j = right;
|
|
44
|
+
swap(buf, left, k);
|
|
45
|
+
if (cmp(buf[right], t) > 0)
|
|
46
|
+
swap(buf, right, left);
|
|
47
|
+
while (i < j) {
|
|
48
|
+
swap(buf, i, j);
|
|
49
|
+
i++;
|
|
50
|
+
j--;
|
|
51
|
+
while (compare(buf[i], t) < 0)
|
|
52
|
+
i++;
|
|
53
|
+
while (compare(buf[j], t) > 0)
|
|
54
|
+
j--;
|
|
55
|
+
}
|
|
56
|
+
if (compare(buf[left], t) === 0) {
|
|
57
|
+
swap(buf, left, j);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
j++;
|
|
61
|
+
swap(buf, j, right);
|
|
62
|
+
}
|
|
63
|
+
if (j <= k)
|
|
64
|
+
left = j + 1;
|
|
65
|
+
if (k <= j)
|
|
66
|
+
right = j - 1;
|
|
67
|
+
}
|
|
68
|
+
return buf;
|
|
69
|
+
};
|
package/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export * from "./ensure-array.js";
|
|
|
8
8
|
export * from "./ensure-iterable.js";
|
|
9
9
|
export * from "./find.js";
|
|
10
10
|
export * from "./fill-range.js";
|
|
11
|
+
export * from "./floyd-rivest.js";
|
|
11
12
|
export * from "./fuzzy-match.js";
|
|
12
13
|
export * from "./is-sorted.js";
|
|
13
14
|
export * from "./insert.js";
|
package/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export * from "./ensure-array.js";
|
|
|
8
8
|
export * from "./ensure-iterable.js";
|
|
9
9
|
export * from "./find.js";
|
|
10
10
|
export * from "./fill-range.js";
|
|
11
|
+
export * from "./floyd-rivest.js";
|
|
11
12
|
export * from "./fuzzy-match.js";
|
|
12
13
|
export * from "./is-sorted.js";
|
|
13
14
|
export * from "./insert.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/arrays",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Array / Arraylike utilities",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -107,6 +107,9 @@
|
|
|
107
107
|
"./find": {
|
|
108
108
|
"default": "./find.js"
|
|
109
109
|
},
|
|
110
|
+
"./floyd-rivest": {
|
|
111
|
+
"default": "./floyd-rivest.js"
|
|
112
|
+
},
|
|
110
113
|
"./fuzzy-match": {
|
|
111
114
|
"default": "./fuzzy-match.js"
|
|
112
115
|
},
|
|
@@ -153,5 +156,5 @@
|
|
|
153
156
|
"thi.ng": {
|
|
154
157
|
"year": 2018
|
|
155
158
|
},
|
|
156
|
-
"gitHead": "
|
|
159
|
+
"gitHead": "28bb74c67217a352d673b6efdab234921d4a370e\n"
|
|
157
160
|
}
|