@gkucmierz/utils 1.24.0 → 1.25.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/package-lock.json +2 -2
- package/package.json +1 -1
- package/spec/binary-search.spec.mjs +76 -0
- package/src/binary-search.mjs +46 -0
- package/src/copy-case.mjs +6 -1
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gkucmierz/utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.0",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@gkucmierz/utils",
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.25.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"husky": "^8.0.1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
import {
|
|
3
3
|
binarySearchArr,
|
|
4
|
+
binarySearchLE,
|
|
5
|
+
binarySearchGE,
|
|
6
|
+
binarySearchRangeIncl,
|
|
4
7
|
} from '../src/binary-search.mjs';
|
|
5
8
|
|
|
6
9
|
describe('binarySearchArr', () => {
|
|
@@ -13,3 +16,76 @@ describe('binarySearchArr', () => {
|
|
|
13
16
|
expect(binarySearchArr([1, 2, 3, 4], 5)).toBe(-1);
|
|
14
17
|
});
|
|
15
18
|
});
|
|
19
|
+
|
|
20
|
+
describe('binarySearchLE', () => {
|
|
21
|
+
it('mid group', () => {
|
|
22
|
+
const arr = [0,1,2,2,3];
|
|
23
|
+
expect(binarySearchLE(arr, -100)).toBe(-1);
|
|
24
|
+
expect(binarySearchLE(arr, 0)).toBe(0);
|
|
25
|
+
expect(binarySearchLE(arr, 1)).toBe(1);
|
|
26
|
+
expect(binarySearchLE(arr, 2)).toBe(3);
|
|
27
|
+
expect(binarySearchLE(arr, 3)).toBe(4);
|
|
28
|
+
expect(binarySearchLE(arr, 100)).toBe(4);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('begin group', () => {
|
|
32
|
+
const arr = [2,2,3];
|
|
33
|
+
expect(binarySearchLE(arr, -100)).toBe(-1);
|
|
34
|
+
expect(binarySearchLE(arr, 2)).toBe(1);
|
|
35
|
+
expect(binarySearchLE(arr, 3)).toBe(2);
|
|
36
|
+
expect(binarySearchLE(arr, 100)).toBe(2);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('end group', () => {
|
|
40
|
+
const arr = [1,2,2];
|
|
41
|
+
expect(binarySearchLE(arr, -100)).toBe(-1);
|
|
42
|
+
expect(binarySearchLE(arr, 1)).toBe(0);
|
|
43
|
+
expect(binarySearchLE(arr, 2)).toBe(2);
|
|
44
|
+
expect(binarySearchLE(arr, 100)).toBe(2);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
describe('binarySearchGE', () => {
|
|
49
|
+
it('mid group', () => {
|
|
50
|
+
const arr = [0,1,2,2,3];
|
|
51
|
+
expect(binarySearchGE(arr, -100)).toBe(0);
|
|
52
|
+
expect(binarySearchGE(arr, 0)).toBe(0);
|
|
53
|
+
expect(binarySearchGE(arr, 1)).toBe(1);
|
|
54
|
+
expect(binarySearchGE(arr, 2)).toBe(2);
|
|
55
|
+
expect(binarySearchGE(arr, 3)).toBe(4);
|
|
56
|
+
expect(binarySearchGE(arr, 100)).toBe(5);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('begin group', () => {
|
|
60
|
+
const arr = [2,2,3];
|
|
61
|
+
expect(binarySearchGE(arr, -100)).toBe(0);
|
|
62
|
+
expect(binarySearchGE(arr, 2)).toBe(0);
|
|
63
|
+
expect(binarySearchGE(arr, 3)).toBe(2);
|
|
64
|
+
expect(binarySearchGE(arr, 100)).toBe(3);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('end group', () => {
|
|
68
|
+
const arr = [1,2,2];
|
|
69
|
+
expect(binarySearchGE(arr, -100)).toBe(0);
|
|
70
|
+
expect(binarySearchGE(arr, 1)).toBe(0);
|
|
71
|
+
expect(binarySearchGE(arr, 2)).toBe(1);
|
|
72
|
+
expect(binarySearchGE(arr, 100)).toBe(3);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe('binarySearchRangeIncl', () => {
|
|
77
|
+
it('basic', () => {
|
|
78
|
+
const arr = [0,1,1,3];
|
|
79
|
+
const check = [-10, ...arr, 10];
|
|
80
|
+
const expected = [
|
|
81
|
+
[0, -1],
|
|
82
|
+
[0, 0], [1, 2], [1, 2], [3, 3],
|
|
83
|
+
[4, 3],
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
for (let i = 0; i < check.length; ++i) {
|
|
87
|
+
expect(binarySearchRangeIncl(arr, check[i])).toEqual(expected[i]);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
package/src/binary-search.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
|
|
2
|
+
// binary search array exact element
|
|
3
|
+
// in sorted array
|
|
2
4
|
export const binarySearchArr = (arr, target) => {
|
|
3
5
|
let [a, b] = [0, arr.length];
|
|
4
6
|
let lm;
|
|
@@ -17,3 +19,47 @@ export const binarySearchArr = (arr, target) => {
|
|
|
17
19
|
}
|
|
18
20
|
return -1;
|
|
19
21
|
};
|
|
22
|
+
|
|
23
|
+
// binary search array less or equal element
|
|
24
|
+
export const binarySearchLE = (arr, target) => {
|
|
25
|
+
let [a, b] = [0, arr.length];
|
|
26
|
+
let lm;
|
|
27
|
+
while (b - a > 0) {
|
|
28
|
+
const mid = (a + b) / 2 | 0;
|
|
29
|
+
const val = arr[mid];
|
|
30
|
+
if (target < val) {
|
|
31
|
+
b = mid;
|
|
32
|
+
} else if (val <= target) {
|
|
33
|
+
a = mid;
|
|
34
|
+
}
|
|
35
|
+
if (lm === mid) return mid;
|
|
36
|
+
lm = mid;
|
|
37
|
+
}
|
|
38
|
+
return -1;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// binary search array greater or equal element
|
|
42
|
+
export const binarySearchGE = (arr, target) => {
|
|
43
|
+
let [a, b] = [0, arr.length];
|
|
44
|
+
let lm;
|
|
45
|
+
while (b - a > 0) {
|
|
46
|
+
const mid = (a + b) / 2 | 0;
|
|
47
|
+
const val = arr[mid];
|
|
48
|
+
if (target > val) {
|
|
49
|
+
a = mid;
|
|
50
|
+
} else if (val >= target) {
|
|
51
|
+
b = mid;
|
|
52
|
+
}
|
|
53
|
+
if (lm === mid) return mid + 1;
|
|
54
|
+
lm = mid;
|
|
55
|
+
}
|
|
56
|
+
return 0;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// binary search for range of elements in array inclusive
|
|
60
|
+
export const binarySearchRangeIncl = (arr, target) => {
|
|
61
|
+
return [
|
|
62
|
+
binarySearchGE(arr, target),
|
|
63
|
+
binarySearchLE(arr, target),
|
|
64
|
+
];
|
|
65
|
+
};
|
package/src/copy-case.mjs
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Copy the case of a string into another.
|
|
4
|
+
* @param {string} target String to change the case.
|
|
5
|
+
* @param {string} source Source of case pattern.
|
|
6
|
+
* @return {string} Converted string.
|
|
7
|
+
*/
|
|
3
8
|
export const copyCase = (word, from) => {
|
|
4
9
|
const isLower = w => w.toLowerCase() === w;
|
|
5
10
|
const isUpper = w => w.toUpperCase() === w;
|