@softsky/utils 2.6.0 → 2.7.1

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/README.md CHANGED
@@ -84,6 +84,9 @@ Only deletes last encountered.
84
84
 
85
85
  Returns index of deleted value.
86
86
 
87
+ ---
88
+ __function__ `reverse` - Reverse part of array
89
+
87
90
  ---
88
91
 
89
92
 
@@ -291,6 +294,21 @@ If isTarget is omitted becomes floodfill.
291
294
  Returns a target and map of parents.
292
295
  You can use `unfoldPathfindingResult()` to get array of nodes.
293
296
 
297
+ ---
298
+ __function__ `knapsack` - Knapsack find best way to get maximum value in limited capacity
299
+
300
+ ---
301
+ __function__ `hamiltonianCycle` - Find min path between points. You need to supply 2-dim array
302
+ where first index is a point and second index is a distance from this point to another.
303
+ Put infinity if where are no path. Returns cycle (start and end at the same point)
304
+ Original: https://github.com/qntm/held-karp
305
+
306
+ ---
307
+ __function__ `traverseByNearestNeighbor` - Traverse all points by nearest neighbor. Should be able to go from any point to any other point.
308
+
309
+ ---
310
+ __function__ `twoOpt` - 2-opt improvement
311
+
294
312
  ---
295
313
 
296
314
 
@@ -505,14 +523,20 @@ Returns clear function.
505
523
  For cron string syntax check __getNextCron()__ description
506
524
 
507
525
  ---
508
- __function__ `getNextCron` - Find next cron date after passed date.
526
+ __function__ `getNextCron` - Find next cron date after passed date. This function __DOES NOT__ implement regular CRON 1 to 1.
509
527
 
510
- This function __DOES NOT__ implement regular CRON 1 to 1.
528
+ 1. [0-999] Milliseconds
529
+ 2. [0-59] Seconds
530
+ 3. [0-59] Minutes
531
+ 4. [0-23] Hours
532
+ 5. [1-31] Dates
533
+ 6. [1-12] Months
534
+ 7. [0-6] Weekdays
511
535
 
512
536
  Main differences:
513
537
  - Weekdays value only 0 to 6 (0 is Sunday)
514
538
  - New supported syntax: __30-60/10__ - means __30,40,50,60__
515
- - Second and millisecond support: __* * * * * 30 999__ - executes every 30 seconds at the end of a second
539
+ - Second and millisecond support: __0,500 300__ - every 30 seconds, two times
516
540
 
517
541
  ---
518
542
  __class__ `SpeedCalculator` - Object that calculates speed, ETA and percent of any measurable task.
package/dist/arrays.d.ts CHANGED
@@ -48,3 +48,5 @@ export declare function removeFromArray<T>(array: T[], value: T): number;
48
48
  * Returns index of deleted value.
49
49
  */
50
50
  export declare function removeLastFromArray<T>(array: T[], value: T): number;
51
+ /** Reverse part of array */
52
+ export declare function reverse<T>(array: T[], start: number, end: number): T[];
package/dist/arrays.js CHANGED
@@ -133,3 +133,14 @@ export function removeLastFromArray(array, value) {
133
133
  array.splice(index, 1);
134
134
  return index;
135
135
  }
136
+ /** Reverse part of array */
137
+ export function reverse(array, start, end) {
138
+ array = [...array];
139
+ const n = ((end - start + 1) / 2) | 0;
140
+ for (let index = 0; index < n; index++) {
141
+ const temporary = array[start + index];
142
+ array[start + index] = array[end - index];
143
+ array[end - index] = temporary;
144
+ }
145
+ return array;
146
+ }
package/dist/graphs.d.ts CHANGED
@@ -59,3 +59,21 @@ export declare function dfs<T>(options: {
59
59
  parents: Map<T, T>;
60
60
  target?: T;
61
61
  };
62
+ /** Knapsack find best way to get maximum value in limited capacity */
63
+ export declare function knapsack(weights: number[], values: number[], capacity: number): {
64
+ weight: number;
65
+ items: number[];
66
+ };
67
+ /**
68
+ * Find min path between points. You need to supply 2-dim array
69
+ * where first index is a point and second index is a distance from this point to another.
70
+ * Put infinity if where are no path. Returns cycle (start and end at the same point)
71
+ * Original: https://github.com/qntm/held-karp
72
+ */
73
+ export declare function hamiltonianCycle(distribution: number[][]): number[];
74
+ /**
75
+ * Traverse all points by nearest neighbor. Should be able to go from any point to any other point.
76
+ */
77
+ export declare function traverseByNearestNeighbor(distribution: number[][]): number[];
78
+ /** 2-opt improvement */
79
+ export declare function twoOpt(tour: number[], distribution: number[][]): number[];
package/dist/graphs.js CHANGED
@@ -109,3 +109,149 @@ export function dfs(options) {
109
109
  parents,
110
110
  };
111
111
  }
112
+ /** Knapsack find best way to get maximum value in limited capacity */
113
+ export function knapsack(weights, values, capacity) {
114
+ const n = weights.length;
115
+ const dp = Array.from({ length: n + 1 }, () => new Array(capacity + 1).fill(0));
116
+ for (let index = 1; index <= n; index++) {
117
+ const w = weights[index - 1];
118
+ const v = values[index - 1];
119
+ const dpc = dp[index];
120
+ const dpl = dp[index - 1];
121
+ for (let c = 0; c <= capacity; c++)
122
+ dpc[c] = w > c ? dpl[c] : Math.max(dpl[c], dpl[c - w] + v);
123
+ }
124
+ const items = [];
125
+ let c = capacity;
126
+ for (let index = n; index > 0 && c > 0; index--) {
127
+ if (dp[index][c] !== dp[index - 1][c]) {
128
+ items.push(index - 1);
129
+ c -= weights[index - 1];
130
+ }
131
+ }
132
+ return { weight: dp[n][capacity], items: items.reverse() };
133
+ }
134
+ /**
135
+ * Find min path between points. You need to supply 2-dim array
136
+ * where first index is a point and second index is a distance from this point to another.
137
+ * Put infinity if where are no path. Returns cycle (start and end at the same point)
138
+ * Original: https://github.com/qntm/held-karp
139
+ */
140
+ export function hamiltonianCycle(distribution) {
141
+ const n = distribution.length;
142
+ if (n === 1)
143
+ return [0, 0];
144
+ const all = (1 << (n - 1)) - 1;
145
+ const length = new Float64Array((1 << (n - 1)) * (n - 1));
146
+ const previous = new Uint8Array((1 << (n - 1)) * (n - 1));
147
+ let S = 0;
148
+ do {
149
+ S++;
150
+ let v = n - 1;
151
+ do {
152
+ v--;
153
+ const S2 = S ^ (1 << v);
154
+ if (S2 < S) {
155
+ let bestL = 0;
156
+ let bestU = 0;
157
+ if (S2) {
158
+ bestL = Infinity;
159
+ let u = n - 1;
160
+ do {
161
+ u--;
162
+ if (S2 & (1 << u)) {
163
+ const l = length[(n - 1) * S2 + u] + distribution[u][v];
164
+ if (l <= bestL) {
165
+ bestL = l;
166
+ bestU = u;
167
+ }
168
+ }
169
+ } while (u);
170
+ }
171
+ else {
172
+ bestL = distribution[n - 1][v];
173
+ bestU = n - 1;
174
+ }
175
+ length[(n - 1) * S + v] = bestL;
176
+ previous[(n - 1) * S + v] = bestU;
177
+ }
178
+ } while (v);
179
+ } while (S < all);
180
+ let bestL = Infinity;
181
+ let bestU = -1;
182
+ let u = n - 1;
183
+ do {
184
+ u--;
185
+ const l = length[(n - 1) * all + u] + distribution[u][n - 1];
186
+ if (l <= bestL) {
187
+ bestL = l;
188
+ bestU = u;
189
+ }
190
+ } while (u);
191
+ const cycle = [n - 1];
192
+ u = bestU;
193
+ S = all;
194
+ while (u !== n - 1) {
195
+ cycle.unshift(u);
196
+ const S2 = S ^ (1 << u);
197
+ u = previous[(n - 1) * S + u];
198
+ S = S2;
199
+ }
200
+ const index = cycle.indexOf(0);
201
+ return [...cycle.slice(index), ...cycle.slice(0, index), 0];
202
+ }
203
+ /**
204
+ * Traverse all points by nearest neighbor. Should be able to go from any point to any other point.
205
+ */
206
+ export function traverseByNearestNeighbor(distribution) {
207
+ const n = distribution.length;
208
+ const toVisit = new Array(n).fill(true);
209
+ const path = [0];
210
+ let last = 0;
211
+ toVisit[0] = false;
212
+ for (let index = 1; index < n; index++) {
213
+ let nearest = -1;
214
+ let nearestDistribution = Infinity;
215
+ for (let index = 0; index < n; index++) {
216
+ if (toVisit[index] && distribution[last][index] < nearestDistribution) {
217
+ nearest = index;
218
+ nearestDistribution = distribution[last][index];
219
+ }
220
+ }
221
+ path.push(nearest);
222
+ last = nearest;
223
+ toVisit[nearest] = false;
224
+ }
225
+ return path;
226
+ }
227
+ /** 2-opt improvement */
228
+ export function twoOpt(tour, distribution) {
229
+ let improved = true;
230
+ const nStart = tour.length - 2;
231
+ const nEnd = tour.length - 1;
232
+ while (improved) {
233
+ improved = false;
234
+ for (let start = 1; start < nStart; start++) {
235
+ for (let end = start + 1; end < nEnd; end++) {
236
+ const t0 = distribution[tour[start - 1]];
237
+ const t1 = tour[start];
238
+ const tk1 = tour[end];
239
+ const tk2 = tour[end + 1];
240
+ if (t0[tk1] +
241
+ distribution[t1][tk2] -
242
+ t0[t1] -
243
+ distribution[tk1][tk2] <
244
+ -1e-9) {
245
+ const n = ((end - start + 1) / 2) | 0;
246
+ for (let index = 0; index < n; index++) {
247
+ const temporary = tour[start + index];
248
+ tour[start + index] = tour[end - index];
249
+ tour[end - index] = temporary;
250
+ }
251
+ improved = true;
252
+ }
253
+ }
254
+ }
255
+ }
256
+ return tour;
257
+ }
package/dist/time.d.ts CHANGED
@@ -22,14 +22,21 @@ export declare function setSafeInterval(handler: AnyFunction, delay: number): ()
22
22
  * Returns clear function.
23
23
  * For cron string syntax check __getNextCron()__ description */
24
24
  export declare function cronInterval(run: () => unknown, cronString: string): () => void;
25
- /** Find next cron date after passed date.
25
+ /** Find next cron date after passed date. This function __DOES NOT__ implement regular CRON 1 to 1.
26
26
  *
27
- * This function __DOES NOT__ implement regular CRON 1 to 1.
27
+ * 1. [0-999] Milliseconds
28
+ * 2. [0-59] Seconds
29
+ * 3. [0-59] Minutes
30
+ * 4. [0-23] Hours
31
+ * 5. [1-31] Dates
32
+ * 6. [1-12] Months
33
+ * 7. [0-6] Weekdays
28
34
  *
29
35
  * Main differences:
30
36
  * - Weekdays value only 0 to 6 (0 is Sunday)
31
37
  * - New supported syntax: __30-60/10__ - means __30,40,50,60__
32
- * - Second and millisecond support: __* * * * * 30 999__ - executes every 30 seconds at the end of a second */
38
+ * - Second and millisecond support: __0,500 300__ - every 30 seconds, two times
39
+ * */
33
40
  export declare function getNextCron(cronString: string, datetime?: Date): Date;
34
41
  /**
35
42
  * Object that calculates speed, ETA and percent of any measurable task.
package/dist/time.js CHANGED
@@ -79,14 +79,21 @@ export function cronInterval(run, cronString) {
79
79
  clearTimeout(timeout);
80
80
  };
81
81
  }
82
- /** Find next cron date after passed date.
82
+ /** Find next cron date after passed date. This function __DOES NOT__ implement regular CRON 1 to 1.
83
83
  *
84
- * This function __DOES NOT__ implement regular CRON 1 to 1.
84
+ * 1. [0-999] Milliseconds
85
+ * 2. [0-59] Seconds
86
+ * 3. [0-59] Minutes
87
+ * 4. [0-23] Hours
88
+ * 5. [1-31] Dates
89
+ * 6. [1-12] Months
90
+ * 7. [0-6] Weekdays
85
91
  *
86
92
  * Main differences:
87
93
  * - Weekdays value only 0 to 6 (0 is Sunday)
88
94
  * - New supported syntax: __30-60/10__ - means __30,40,50,60__
89
- * - Second and millisecond support: __* * * * * 30 999__ - executes every 30 seconds at the end of a second */
95
+ * - Second and millisecond support: __0,500 300__ - every 30 seconds, two times
96
+ * */
90
97
  export function getNextCron(cronString, datetime = new Date()) {
91
98
  const cron = cronString.split(' ');
92
99
  for (let index = cron.length; index < 7; index++)
@@ -244,6 +251,7 @@ export class SpeedCalculator {
244
251
  : {
245
252
  speed,
246
253
  percent: this.sum / this.size,
254
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-conversion
247
255
  eta: ~~((this.size - this.sum) / speed) * 1000,
248
256
  };
249
257
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softsky/utils",
3
- "version": "2.6.0",
3
+ "version": "2.7.1",
4
4
  "description": "JavaScript/TypeScript utilities",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {