list-toolkit 1.0.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/cjs/MinHeap.js ADDED
@@ -0,0 +1,261 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _utils = require("./utils.js");
8
+ // the following functions are inlined:
9
+
10
+ // const left = i => (i << 1) + 1;
11
+ // const right = i => (i + 1) << 1;
12
+ // const parent = i => (i - 1) >> 1;
13
+
14
+ const defaultLess = (a, b) => a < b;
15
+ const defaultEqual = (a, b) => a === b;
16
+ const up = (array, i, less = defaultLess) => {
17
+ for (let p = i - 1 >> 1; i > 0; i = p, p = i - 1 >> 1) {
18
+ const iValue = array[i],
19
+ pValue = array[p];
20
+ if (!less(iValue, pValue)) break;
21
+ array[i] = pValue;
22
+ array[p] = iValue;
23
+ }
24
+ return array;
25
+ };
26
+ const down = (array, i, less = defaultLess, n = array.length) => {
27
+ for (;;) {
28
+ const l = (i << 1) + 1;
29
+ if (l >= n) break;
30
+ let c = l,
31
+ cValue = array[c];
32
+ const r = c + 1;
33
+ if (r < n) {
34
+ const rValue = array[r];
35
+ if (less(rValue, cValue)) {
36
+ c = r;
37
+ cValue = rValue;
38
+ }
39
+ }
40
+ const iValue = array[i];
41
+ if (!less(cValue, iValue)) break;
42
+ array[i] = cValue;
43
+ array[c] = iValue;
44
+ i = c;
45
+ }
46
+ return array;
47
+ };
48
+ class MinHeap {
49
+ constructor(options, ...args) {
50
+ (0, _utils.copyOptions)(this, MinHeap.defaults, options);
51
+ this.array = [];
52
+ this.merge(...args);
53
+ }
54
+ get length() {
55
+ return this.array.length;
56
+ }
57
+ get isEmpty() {
58
+ return !this.array.length;
59
+ }
60
+ get top() {
61
+ return this.array[0];
62
+ }
63
+ clear() {
64
+ this.array = [];
65
+ return this;
66
+ }
67
+ pop() {
68
+ // return MinHeap.pop(this.array, this.less); // inlined
69
+ switch (this.array.length) {
70
+ case 0:
71
+ return;
72
+ case 1:
73
+ return this.array.pop();
74
+ }
75
+ const top = this.array[0];
76
+ this.array[0] = this.array.pop();
77
+ // down(this.array, 0, this.less); // inlined
78
+ const n = this.array.length;
79
+ for (let i = 0;;) {
80
+ const l = (i << 1) + 1;
81
+ if (l >= n) break;
82
+ let c = l,
83
+ cValue = this.array[c];
84
+ const r = c + 1;
85
+ if (r < n) {
86
+ const rValue = this.array[r];
87
+ if (this.less(rValue, cValue)) {
88
+ c = r;
89
+ cValue = rValue;
90
+ }
91
+ }
92
+ const iValue = this.array[i];
93
+ if (!this.less(cValue, iValue)) break;
94
+ this.array[i] = cValue;
95
+ this.array[c] = iValue;
96
+ i = c;
97
+ }
98
+ return top;
99
+ }
100
+ push(value) {
101
+ // MinHeap.push(this.array, value, this.less); // inlined
102
+ let i = this.array.length;
103
+ this.array.push(value);
104
+ // up(this.array, i, this.less); // inlined
105
+ for (let p = i - 1 >> 1; i > 0; i = p, p = i - 1 >> 1) {
106
+ const iValue = this.array[i],
107
+ pValue = this.array[p];
108
+ if (!this.less(iValue, pValue)) break;
109
+ this.array[i] = pValue;
110
+ this.array[p] = iValue;
111
+ }
112
+ return this;
113
+ }
114
+ pushPop(value) {
115
+ // return MinHeap.pushPop(this.array, value, this.less); // inlined
116
+ if (!this.array.length || this.less(value, this.array[0])) return value;
117
+ const top = this.array[0];
118
+ this.array[0] = value;
119
+ // down(this.array, 0, this.less); // inlined
120
+ const n = this.array.length;
121
+ for (let i = 0;;) {
122
+ const l = (i << 1) + 1;
123
+ if (l >= n) break;
124
+ let c = l,
125
+ cValue = this.array[c];
126
+ const r = c + 1;
127
+ if (r < n) {
128
+ const rValue = this.array[r];
129
+ if (this.less(rValue, cValue)) {
130
+ c = r;
131
+ cValue = rValue;
132
+ }
133
+ }
134
+ const iValue = this.array[i];
135
+ if (!this.less(cValue, iValue)) break;
136
+ this.array[i] = cValue;
137
+ this.array[c] = iValue;
138
+ i = c;
139
+ }
140
+ return top;
141
+ }
142
+ replaceTop(value) {
143
+ // return MinHeap.replaceTop(this.array, value, this.less); // inlined
144
+ const top = this.array[0];
145
+ this.array[0] = value;
146
+ // down(this.array, 0, this.less); // inlined
147
+ const n = this.array.length;
148
+ for (let i = 0;;) {
149
+ const l = (i << 1) + 1;
150
+ if (l >= n) break;
151
+ let c = l,
152
+ cValue = this.array[c];
153
+ const r = c + 1;
154
+ if (r < n) {
155
+ const rValue = this.array[r];
156
+ if (this.less(rValue, cValue)) {
157
+ c = r;
158
+ cValue = rValue;
159
+ }
160
+ }
161
+ const iValue = this.array[i];
162
+ if (!this.less(cValue, iValue)) break;
163
+ this.array[i] = cValue;
164
+ this.array[c] = iValue;
165
+ i = c;
166
+ }
167
+ return top;
168
+ }
169
+ releaseSorted() {
170
+ MinHeap.sort(this.array, this.less);
171
+ const array = this.array;
172
+ this.array = [];
173
+ return array;
174
+ }
175
+ merge(...args) {
176
+ if (!args.length) return this;
177
+ this.array = MinHeap.build(this.array.concat(...args.map(item => {
178
+ if (item instanceof MinHeap) return item.array;
179
+ if (!item) return [];
180
+ return item;
181
+ })), this.less);
182
+ return this;
183
+ }
184
+ make(...args) {
185
+ return new MinHeap(this, ...args);
186
+ }
187
+ clone() {
188
+ const heap = new MinHeap(this);
189
+ heap.array = this.array.slice(0);
190
+ return heap;
191
+ }
192
+ static build(array, less = MinHeap.defaults.less) {
193
+ if (array.length <= 1) return array;
194
+ for (let n = array.length, j = (n >> 1) - 1; j >= 0; --j) {
195
+ // down(array, j, less, n); // inlined
196
+ for (let i = j;;) {
197
+ const l = (i << 1) + 1;
198
+ if (l >= n) break;
199
+ let c = l,
200
+ cValue = array[c];
201
+ const r = c + 1;
202
+ if (r < n) {
203
+ const rValue = array[r];
204
+ if (less(rValue, cValue)) {
205
+ c = r;
206
+ cValue = rValue;
207
+ }
208
+ }
209
+ const iValue = array[i];
210
+ if (!less(cValue, iValue)) break;
211
+ array[i] = cValue;
212
+ array[c] = iValue;
213
+ i = c;
214
+ }
215
+ }
216
+ return array;
217
+ }
218
+ static pop(heapArray, less = MinHeap.defaults.less) {
219
+ switch (heapArray.length) {
220
+ case 0:
221
+ return;
222
+ case 1:
223
+ return heapArray.pop();
224
+ }
225
+ const top = heapArray[0];
226
+ heapArray[0] = heapArray.pop();
227
+ down(heapArray, 0, less);
228
+ return top;
229
+ }
230
+ static push(heapArray, item, less = MinHeap.defaults.less) {
231
+ const i = heapArray.length;
232
+ heapArray.push(item);
233
+ return up(heapArray, i, less);
234
+ }
235
+ static pushPop(heapArray, item, less = MinHeap.defaults.less) {
236
+ if (!heapArray.length || less(item, heapArray[0])) return item;
237
+ const top = heapArray[0];
238
+ heapArray[0] = item;
239
+ down(heapArray, 0, less);
240
+ return top;
241
+ }
242
+ static replaceTop(heapArray, item, less = MinHeap.defaults.less) {
243
+ const top = heapArray[0];
244
+ heapArray[0] = item;
245
+ down(heapArray, 0, less);
246
+ return top;
247
+ }
248
+ static sort(heapArray, less = MinHeap.defaults.less) {
249
+ if (heapArray.length <= 1) return heapArray;
250
+ for (let n = heapArray.length - 1; n; --n) {
251
+ [heapArray[0], heapArray[n]] = [heapArray[n], heapArray[0]];
252
+ down(heapArray, 0, less, n);
253
+ }
254
+ return heapArray;
255
+ }
256
+ }
257
+ MinHeap.defaults = {
258
+ less: defaultLess,
259
+ equal: defaultEqual
260
+ };
261
+ var _default = exports.default = MinHeap;
package/cjs/SList.js ADDED
@@ -0,0 +1,336 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ class SListNode {
8
+ constructor() {
9
+ this.next = this;
10
+ }
11
+ }
12
+ const pop = prev => {
13
+ const node = prev.next;
14
+ prev.next = node.next;
15
+ node.next = node;
16
+ return {
17
+ node,
18
+ list: prev
19
+ };
20
+ };
21
+ const extract = (prevFrom, nodeTo) => {
22
+ const node = prevFrom.next;
23
+ if (prevFrom === nodeTo) return {
24
+ prev: prevFrom,
25
+ node
26
+ };
27
+ prevFrom.next = nodeTo.next;
28
+ nodeTo.next = node;
29
+ return {
30
+ prev: nodeTo,
31
+ node
32
+ };
33
+ };
34
+ const splice = (prev1, {
35
+ prev,
36
+ node
37
+ }) => {
38
+ prev.next = prev1.next;
39
+ prev1.next = node;
40
+ return prev1;
41
+ };
42
+ const getPrevPrev = (list, node) => {
43
+ let prev = list,
44
+ current = prev.next;
45
+ while (current.next !== list) {
46
+ if (node && current.next === node) return prev;
47
+ prev = current;
48
+ current = prev.next;
49
+ }
50
+ if (node) {
51
+ if (list.next === node) return current;
52
+ throw new Error('node does not belong to the list');
53
+ }
54
+ return prev;
55
+ };
56
+ const getPrev = (list, node) => {
57
+ return getPrevPrev(list, node).next;
58
+ };
59
+ class SListValueNode extends SListNode {
60
+ constructor(value) {
61
+ super();
62
+ this.value = value;
63
+ }
64
+ addAfter(value) {
65
+ const node = new SListValueNode(value);
66
+ splice(this, {
67
+ prev: node,
68
+ node
69
+ });
70
+ return this;
71
+ }
72
+ insertAfter(list) {
73
+ const node = getPrev(pop(list).list);
74
+ splice(this, {
75
+ prev: node,
76
+ node
77
+ });
78
+ return this;
79
+ }
80
+ }
81
+ class SList extends SListNode {
82
+ get isEmpty() {
83
+ return this.next === this;
84
+ }
85
+ get front() {
86
+ return this.next;
87
+ }
88
+ getBack() {
89
+ return getPrev(this);
90
+ }
91
+ getLength() {
92
+ let n = 0;
93
+ for (let p = this.next; p !== this; ++n, p = p.next);
94
+ return n;
95
+ }
96
+ getPtr() {
97
+ return new SList.SListPtr(this);
98
+ }
99
+ popFront() {
100
+ if (this.next !== this) {
101
+ return pop(this).node.value;
102
+ }
103
+ }
104
+ popBack() {
105
+ if (this.next !== this) {
106
+ const prevLast = getPrevPrev(this);
107
+ return pop(prevLast).node.value;
108
+ }
109
+ }
110
+ pushFront(value) {
111
+ const node = new SListValueNode(value);
112
+ splice(this, {
113
+ prev: node,
114
+ node
115
+ });
116
+ return this;
117
+ }
118
+ pushBack(value) {
119
+ const node = new SListValueNode(value),
120
+ last = getPrev(this);
121
+ splice(last, {
122
+ prev: node,
123
+ node
124
+ });
125
+ return this;
126
+ }
127
+ appendFront(list) {
128
+ if (list.next === list) return this;
129
+ let prevFrom = list,
130
+ nodeTo = getPrev(list);
131
+ splice(this, extract(prevFrom, nodeTo));
132
+ return this;
133
+ }
134
+ appendBack(list) {
135
+ if (list.next === list) return this;
136
+ let prevFrom = list,
137
+ nodeTo = getPrev(list),
138
+ last = getPrev(this);
139
+ splice(last, extract(prevFrom, nodeTo));
140
+ return this;
141
+ }
142
+ moveToFront(node) {
143
+ let prev;
144
+ if (node instanceof SList.SListPtr) {
145
+ prev = node.prev;
146
+ node = node.node;
147
+ if (this.next === node) return this;
148
+ } else {
149
+ if (this.next === node) return this;
150
+ prev = getPrev(this, node);
151
+ }
152
+ splice(this, extract(prev, node));
153
+ return this;
154
+ }
155
+ moveToBack(node) {
156
+ let prev;
157
+ if (node instanceof SList.SListPtr) {
158
+ prev = node.prev;
159
+ node = node.node;
160
+ } else {
161
+ prev = getPrev(this, node);
162
+ }
163
+ const last = getPrev(this);
164
+ splice(last, extract(prev, node));
165
+ return this;
166
+ }
167
+ clear() {
168
+ this.next = this;
169
+ return this;
170
+ }
171
+ remove(from, to = from) {
172
+ const prevFrom = from instanceof SList.SListPtr ? from.prev : getPrev(this, from),
173
+ nodeTo = to instanceof SList.SListPtr ? to.node : to;
174
+ extract(prevFrom, nodeTo);
175
+ return this;
176
+ }
177
+ extract(from, to) {
178
+ const prevFrom = from instanceof SList.SListPtr ? from.prev : getPrev(this, from),
179
+ nodeTo = to instanceof SList.SListPtr ? to.node : to;
180
+ return splice(new SList(), extract(prevFrom, nodeTo));
181
+ }
182
+ reverse() {
183
+ let prev = this,
184
+ current = prev.next;
185
+ while (current !== this) {
186
+ const next = current.next;
187
+ current.next = prev;
188
+ prev = current;
189
+ current = next;
190
+ }
191
+ this.next = prev;
192
+ return this;
193
+ }
194
+ sort(compareFn) {
195
+ let current = this.next;
196
+ for (const value of Array.from(this).sort(compareFn)) {
197
+ current.value = value;
198
+ current = current.next;
199
+ }
200
+ return this;
201
+ }
202
+
203
+ // iterators
204
+
205
+ [Symbol.iterator]() {
206
+ let current = this.next;
207
+ return {
208
+ next: () => {
209
+ if (current === this) return {
210
+ done: true
211
+ };
212
+ const node = current;
213
+ current = current.next;
214
+ return {
215
+ value: node.value
216
+ };
217
+ }
218
+ };
219
+ }
220
+ getIterable(from, to) {
221
+ return {
222
+ [Symbol.iterator]: () => {
223
+ let current = from instanceof SList.SListPtr && from.node || from || this.next;
224
+ const stop = to ? (to instanceof SList.SListPtr && to.node || to).next : this;
225
+ return {
226
+ next: () => {
227
+ if (current === stop) return {
228
+ done: true
229
+ };
230
+ const node = current;
231
+ current = current.next;
232
+ return {
233
+ value: node.value
234
+ };
235
+ }
236
+ };
237
+ }
238
+ };
239
+ }
240
+ getNodeIterable(from, to) {
241
+ return {
242
+ [Symbol.iterator]: () => {
243
+ let current = from instanceof SList.SListPtr && from.node || from || this.next;
244
+ const stop = to ? (to instanceof SList.SListPtr && to.node || to).next : this;
245
+ return {
246
+ next: () => {
247
+ if (current === stop) return {
248
+ done: true
249
+ };
250
+ const node = current;
251
+ current = current.next;
252
+ return {
253
+ value: node
254
+ };
255
+ }
256
+ };
257
+ }
258
+ };
259
+ }
260
+ getPtrIterable(from, to) {
261
+ return {
262
+ [Symbol.iterator]: () => {
263
+ let current = from instanceof SList.SListPtr ? from.clone() : from ? new SList.SListPtr(this, getPrev(this.head, from)) : this.getPtr();
264
+ const stop = to ? (to instanceof SList.SListPtr && to.node || to).next : this;
265
+ return {
266
+ next: () => {
267
+ if (current.node === stop) return {
268
+ done: true
269
+ };
270
+ const value = current.clone();
271
+ current.next();
272
+ return {
273
+ value
274
+ };
275
+ }
276
+ };
277
+ }
278
+ };
279
+ }
280
+
281
+ // helpers
282
+
283
+ makeFrom(values) {
284
+ return SList.from(values);
285
+ }
286
+ pushValuesFront(values) {
287
+ for (const value of values) {
288
+ this.pushFront(value);
289
+ }
290
+ return this;
291
+ }
292
+ appendValuesFront(values) {
293
+ return this.appendFront(SList.from(values));
294
+ }
295
+ static from(values) {
296
+ const list = new SList();
297
+ let prev = list;
298
+ for (const value of values) {
299
+ const node = new SListValueNode(value);
300
+ prev.next = node;
301
+ prev = node;
302
+ }
303
+ prev.next = list;
304
+ return list;
305
+ }
306
+ }
307
+ SList.pop = pop;
308
+ SList.extract = extract;
309
+ SList.splice = splice;
310
+ SList.getPrev = getPrev;
311
+ SList.getPrevPrev = getPrevPrev;
312
+ SList.Node = SListNode;
313
+ SList.ValueNode = SListValueNode;
314
+ SList.prototype.pop = SList.prototype.popFront;
315
+ SList.prototype.push = SList.prototype.pushFront;
316
+ SList.prototype.append = SList.prototype.appendBack;
317
+ SList.SListPtr = class SListPtr {
318
+ constructor(list, prev) {
319
+ this.list = list;
320
+ this.prev = prev || list;
321
+ }
322
+ get node() {
323
+ return this.prev.next;
324
+ }
325
+ get isHead() {
326
+ return this.prev.next === this.list;
327
+ }
328
+ next() {
329
+ this.prev = this.prev.next;
330
+ return this;
331
+ }
332
+ clone() {
333
+ return new SList.SListPtr(this.list, this.prev);
334
+ }
335
+ };
336
+ var _default = exports.default = SList;