@softsky/utils 2.6.0 → 2.7.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/README.md CHANGED
@@ -291,6 +291,19 @@ If isTarget is omitted becomes floodfill.
291
291
  Returns a target and map of parents.
292
292
  You can use `unfoldPathfindingResult()` to get array of nodes.
293
293
 
294
+ ---
295
+ __function__ `knapsack` - Knapsack find best way to get maximum value in limited capacity
296
+
297
+ ---
298
+ __function__ `tspHeldKarp` - Find min path between points. You need to supply 2-dim array
299
+ where first index is a point and second index is a distance from this point to another.
300
+ Put infinity if where are no path. Returns cycle (start and end at the same point)
301
+ Original: https://github.com/qntm/held-karp
302
+
303
+ ---
304
+ __function__ `tspHeldKarpPath` - Look for description of `tspHeldKarp`.
305
+ Returns path without cycle
306
+
294
307
  ---
295
308
 
296
309
 
@@ -505,14 +518,20 @@ Returns clear function.
505
518
  For cron string syntax check __getNextCron()__ description
506
519
 
507
520
  ---
508
- __function__ `getNextCron` - Find next cron date after passed date.
521
+ __function__ `getNextCron` - Find next cron date after passed date. This function __DOES NOT__ implement regular CRON 1 to 1.
509
522
 
510
- This function __DOES NOT__ implement regular CRON 1 to 1.
523
+ 1. [0-999] Milliseconds
524
+ 2. [0-59] Seconds
525
+ 3. [0-59] Minutes
526
+ 4. [0-23] Hours
527
+ 5. [1-31] Dates
528
+ 6. [1-12] Months
529
+ 7. [0-6] Weekdays
511
530
 
512
531
  Main differences:
513
532
  - Weekdays value only 0 to 6 (0 is Sunday)
514
533
  - 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
534
+ - Second and millisecond support: __0,500 300__ - every 30 seconds, two times
516
535
 
517
536
  ---
518
537
  __class__ `SpeedCalculator` - Object that calculates speed, ETA and percent of any measurable task.
package/dist/graphs.d.ts CHANGED
@@ -59,3 +59,26 @@ 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 tspHeldKarp(distribution: number[][]): {
74
+ distance: number;
75
+ path: number[];
76
+ };
77
+ /**
78
+ * Look for description of `tspHeldKarp`.
79
+ * Returns path without cycle
80
+ */
81
+ export declare function tspHeldKarpPath(d: number[][]): {
82
+ distance: number;
83
+ path: number[];
84
+ };
package/dist/graphs.js CHANGED
@@ -109,3 +109,109 @@ 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 tspHeldKarp(distribution) {
141
+ const n = distribution.length;
142
+ if (n === 1)
143
+ return { distance: 0, path: [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 {
202
+ distance: cycle.reduce((accumulator, u, index_, cycle) => accumulator +
203
+ distribution[u][cycle[index_ + 1 in cycle ? index_ + 1 : 0]], 0),
204
+ path: [...cycle.slice(index), ...cycle.slice(0, index), 0],
205
+ };
206
+ }
207
+ /**
208
+ * Look for description of `tspHeldKarp`.
209
+ * Returns path without cycle
210
+ */
211
+ export function tspHeldKarpPath(d) {
212
+ const { distance, path } = tspHeldKarp([
213
+ [0, ...new Array(d.length).fill(0)],
214
+ ...d.map((d2) => [0, ...d2]),
215
+ ]);
216
+ return { distance, path: path.slice(1, -1).map((u) => u - 1) };
217
+ }
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.0",
4
4
  "description": "JavaScript/TypeScript utilities",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {