@obinexusmk2/hypernum 0.1.0 → 0.1.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/LICENSE +21 -21
- package/README.md +355 -256
- package/dist/index.cjs +4 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -7
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/dist/types/{config → src/config}/config-loader.d.ts +0 -0
- package/dist/types/src/config/config-loader.d.ts.map +1 -0
- package/dist/types/{config → src/config}/config-parser.d.ts +0 -0
- package/dist/types/src/config/config-parser.d.ts.map +1 -0
- package/dist/types/{config → src/config}/config-resolver.d.ts +0 -0
- package/dist/types/src/config/config-resolver.d.ts.map +1 -0
- package/dist/types/{config → src/config}/config-source.d.ts +0 -0
- package/dist/types/src/config/config-source.d.ts.map +1 -0
- package/dist/types/{config → src/config}/index.d.ts +0 -0
- package/dist/types/src/config/index.d.ts.map +1 -0
- package/dist/types/{core → src/core}/common.d.ts +0 -0
- package/dist/types/src/core/common.d.ts.map +1 -0
- package/dist/types/{core → src/core}/config.d.ts +0 -0
- package/dist/types/src/core/config.d.ts.map +1 -0
- package/dist/types/{core → src/core}/constants.d.ts +0 -0
- package/dist/types/src/core/constants.d.ts.map +1 -0
- package/dist/types/{core → src/core}/errors.d.ts +0 -0
- package/dist/types/src/core/errors.d.ts.map +1 -0
- package/dist/types/{core → src/core}/hypernum.d.ts +0 -0
- package/dist/types/src/core/hypernum.d.ts.map +1 -0
- package/dist/types/{core → src/core}/index.d.ts +0 -0
- package/dist/types/src/core/index.d.ts.map +1 -0
- package/dist/types/{index.d.ts → src/index.d.ts} +1 -1
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/{operations → src/operations}/arithmetic.d.ts +0 -0
- package/dist/types/src/operations/arithmetic.d.ts.map +1 -0
- package/dist/types/{operations → src/operations}/bitwise.d.ts +0 -0
- package/dist/types/src/operations/bitwise.d.ts.map +1 -0
- package/dist/types/{operations → src/operations}/comparison.d.ts +0 -0
- package/dist/types/src/operations/comparison.d.ts.map +1 -0
- package/dist/types/{operations → src/operations}/conversion.d.ts +0 -0
- package/dist/types/src/operations/conversion.d.ts.map +1 -0
- package/dist/types/{operations → src/operations}/factorial.d.ts +0 -0
- package/dist/types/src/operations/factorial.d.ts.map +1 -0
- package/dist/types/{operations → src/operations}/index.d.ts +0 -0
- package/dist/types/src/operations/index.d.ts.map +1 -0
- package/dist/types/{operations → src/operations}/power.d.ts +0 -0
- package/dist/types/src/operations/power.d.ts.map +1 -0
- package/dist/types/{storage → src/storage}/Heap.d.ts +0 -0
- package/dist/types/src/storage/Heap.d.ts.map +1 -0
- package/dist/types/{storage → src/storage}/index.d.ts +0 -0
- package/dist/types/src/storage/index.d.ts.map +1 -0
- package/dist/types/{structures → src/structures}/ackermann.d.ts +0 -0
- package/dist/types/src/structures/ackermann.d.ts.map +1 -0
- package/dist/types/{structures → src/structures}/big-array.d.ts +0 -0
- package/dist/types/src/structures/big-array.d.ts.map +1 -0
- package/dist/types/{structures → src/structures}/index.d.ts +0 -0
- package/dist/types/src/structures/index.d.ts.map +1 -0
- package/dist/types/{structures → src/structures}/number-tree.d.ts +0 -0
- package/dist/types/src/structures/number-tree.d.ts.map +1 -0
- package/dist/types/{structures → src/structures}/power-tower.d.ts +0 -0
- package/dist/types/src/structures/power-tower.d.ts.map +1 -0
- package/dist/types/{utils → src/utils}/formatting.d.ts +0 -0
- package/dist/types/src/utils/formatting.d.ts.map +1 -0
- package/dist/types/{utils → src/utils}/index.d.ts +0 -0
- package/dist/types/src/utils/index.d.ts.map +1 -0
- package/dist/types/{utils → src/utils}/parser.d.ts +0 -0
- package/dist/types/src/utils/parser.d.ts.map +1 -0
- package/dist/types/{utils → src/utils}/precision.d.ts +0 -0
- package/dist/types/src/utils/precision.d.ts.map +1 -0
- package/dist/types/{utils → src/utils}/validation.d.ts +0 -0
- package/dist/types/src/utils/validation.d.ts.map +1 -0
- package/package.json +169 -164
- package/rollup.config.js +163 -161
- package/src/cli/hypernum.js +272 -0
- package/src/config/config-loader.ts +0 -0
- package/src/config/config-parser.ts +160 -160
- package/src/config/config-resolver.ts +0 -0
- package/src/config/config-source.ts +0 -0
- package/src/config/index.ts +0 -0
- package/src/core/common.ts +184 -184
- package/src/core/config.ts +392 -392
- package/src/core/constants.ts +101 -101
- package/src/core/errors.ts +202 -202
- package/src/core/hypernum.ts +240 -240
- package/src/core/index.ts +4 -4
- package/src/index.ts +179 -182
- package/src/operations/arithmetic.ts +332 -332
- package/src/operations/bitwise.ts +366 -366
- package/src/operations/comparison.ts +271 -271
- package/src/operations/conversion.ts +399 -399
- package/src/operations/factorial.ts +278 -278
- package/src/operations/index.ts +4 -4
- package/src/operations/power.ts +315 -315
- package/src/storage/Heap.ts +237 -237
- package/src/storage/index.ts +0 -0
- package/src/structures/ackermann.ts +232 -232
- package/src/structures/big-array.ts +305 -305
- package/src/structures/index.ts +3 -3
- package/src/structures/number-tree.ts +403 -403
- package/src/structures/power-tower.ts +277 -277
- package/src/types/common.d.ts +356 -356
- package/src/types/core.d.ts +160 -160
- package/src/types/index.d.ts +1 -1
- package/src/utils/formatting.ts +245 -245
- package/src/utils/index.ts +4 -4
- package/src/utils/parser.ts +244 -244
- package/src/utils/precision.ts +216 -216
- package/src/utils/validation.ts +182 -182
- package/tsconfig.json +83 -83
- package/dist/types/config/config-loader.d.ts.map +0 -1
- package/dist/types/config/config-parser.d.ts.map +0 -1
- package/dist/types/config/config-resolver.d.ts.map +0 -1
- package/dist/types/config/config-source.d.ts.map +0 -1
- package/dist/types/config/index.d.ts.map +0 -1
- package/dist/types/core/common.d.ts.map +0 -1
- package/dist/types/core/config.d.ts.map +0 -1
- package/dist/types/core/constants.d.ts.map +0 -1
- package/dist/types/core/errors.d.ts.map +0 -1
- package/dist/types/core/hypernum.d.ts.map +0 -1
- package/dist/types/core/index.d.ts.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/operations/arithmetic.d.ts.map +0 -1
- package/dist/types/operations/bitwise.d.ts.map +0 -1
- package/dist/types/operations/comparison.d.ts.map +0 -1
- package/dist/types/operations/conversion.d.ts.map +0 -1
- package/dist/types/operations/factorial.d.ts.map +0 -1
- package/dist/types/operations/index.d.ts.map +0 -1
- package/dist/types/operations/power.d.ts.map +0 -1
- package/dist/types/storage/Heap.d.ts.map +0 -1
- package/dist/types/storage/index.d.ts.map +0 -1
- package/dist/types/structures/ackermann.d.ts.map +0 -1
- package/dist/types/structures/big-array.d.ts.map +0 -1
- package/dist/types/structures/index.d.ts.map +0 -1
- package/dist/types/structures/number-tree.d.ts.map +0 -1
- package/dist/types/structures/power-tower.d.ts.map +0 -1
- package/dist/types/utils/formatting.d.ts.map +0 -1
- package/dist/types/utils/index.d.ts.map +0 -1
- package/dist/types/utils/parser.d.ts.map +0 -1
- package/dist/types/utils/precision.d.ts.map +0 -1
- package/dist/types/utils/validation.d.ts.map +0 -1
|
@@ -1,306 +1,306 @@
|
|
|
1
|
-
import { Comparator } from '@/core';
|
|
2
|
-
import { MinHeap, MaxHeap } from '../storage/Heap';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Interface for segment tree node operations
|
|
6
|
-
*/
|
|
7
|
-
export interface SegmentTreeNode<T> { value: T;
|
|
8
|
-
lazy?: T;
|
|
9
|
-
start: number;
|
|
10
|
-
end: number;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Type for BigArray operation result
|
|
15
|
-
*/
|
|
16
|
-
export type OperationResult<T> = {
|
|
17
|
-
success: boolean;
|
|
18
|
-
value?: T;
|
|
19
|
-
error?: string;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Options for BigArray initialization
|
|
24
|
-
*/
|
|
25
|
-
export interface BigArrayOptions<T> {
|
|
26
|
-
initialCapacity?: number;
|
|
27
|
-
growthFactor?: number;
|
|
28
|
-
comparator?: Comparator<T>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* A specialized array implementation for handling large numbers and providing
|
|
33
|
-
* efficient operations with segment tree support
|
|
34
|
-
*/
|
|
35
|
-
export class BigArray<T> {
|
|
36
|
-
private data: T[];
|
|
37
|
-
private segmentTree: Array<SegmentTreeNode<T> | null>;
|
|
38
|
-
private readonly growthFactor: number;
|
|
39
|
-
private readonly comparator: Comparator<T>;
|
|
40
|
-
private size: number;
|
|
41
|
-
private capacity: number;
|
|
42
|
-
|
|
43
|
-
constructor(options: BigArrayOptions<T> = {}) {
|
|
44
|
-
const {
|
|
45
|
-
initialCapacity = 16,
|
|
46
|
-
growthFactor = 2,
|
|
47
|
-
comparator = ((a: T, b: T): -1 | 0 | 1 => {
|
|
48
|
-
if (a < b) return -1;
|
|
49
|
-
if (a > b) return 1;
|
|
50
|
-
return 0;
|
|
51
|
-
}) as Comparator<T>
|
|
52
|
-
} = options;
|
|
53
|
-
|
|
54
|
-
this.capacity = initialCapacity;
|
|
55
|
-
this.growthFactor = growthFactor;
|
|
56
|
-
this.comparator = comparator;
|
|
57
|
-
this.size = 0;
|
|
58
|
-
this.data = new Array(this.capacity);
|
|
59
|
-
this.segmentTree = new Array(4 * this.capacity).fill(null);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Gets the current size of the array
|
|
64
|
-
*/
|
|
65
|
-
public getSize(): number {
|
|
66
|
-
return this.size;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Gets the current capacity of the array
|
|
71
|
-
*/
|
|
72
|
-
public getCapacity(): number {
|
|
73
|
-
return this.capacity;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Resizes the internal array when needed
|
|
78
|
-
*/
|
|
79
|
-
private resize(newCapacity: number): void {
|
|
80
|
-
const newData = new Array(newCapacity);
|
|
81
|
-
for (let i = 0; i < this.size; i++) {
|
|
82
|
-
newData[i] = this.data[i];
|
|
83
|
-
}
|
|
84
|
-
this.data = newData;
|
|
85
|
-
this.capacity = newCapacity;
|
|
86
|
-
this.rebuildSegmentTree();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Appends an element to the end of the array
|
|
91
|
-
*/
|
|
92
|
-
public push(value: T): OperationResult<number> {
|
|
93
|
-
try {
|
|
94
|
-
if (this.size >= this.capacity) {
|
|
95
|
-
this.resize(this.capacity * this.growthFactor);
|
|
96
|
-
}
|
|
97
|
-
this.data[this.size] = value;
|
|
98
|
-
this.updateSegmentTree(0, this.size, value);
|
|
99
|
-
this.size++;
|
|
100
|
-
return { success: true, value: this.size - 1 };
|
|
101
|
-
} catch (error) {
|
|
102
|
-
return {
|
|
103
|
-
success: false,
|
|
104
|
-
error: error instanceof Error ? error.message : 'Unknown error during push'
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Removes and returns the last element
|
|
111
|
-
*/
|
|
112
|
-
public pop(): OperationResult<T> {
|
|
113
|
-
if (this.size === 0) {
|
|
114
|
-
return { success: false, error: 'Array is empty' };
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const value = this.data[this.size - 1];
|
|
118
|
-
this.size--;
|
|
119
|
-
|
|
120
|
-
// Shrink array if it's too sparse
|
|
121
|
-
if (this.size < this.capacity / (this.growthFactor * 2)) {
|
|
122
|
-
this.resize(Math.max(16, Math.floor(this.capacity / this.growthFactor)));
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return { success: true, value };
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Gets element at specified index
|
|
130
|
-
*/
|
|
131
|
-
public get(index: number): OperationResult<T> {
|
|
132
|
-
if (index < 0 || index >= this.size) {
|
|
133
|
-
return { success: false, error: 'Index out of bounds' };
|
|
134
|
-
}
|
|
135
|
-
return { success: true, value: this.data[index] };
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Sets element at specified index
|
|
140
|
-
*/
|
|
141
|
-
public set(index: number, value: T): OperationResult<T> {
|
|
142
|
-
if (index < 0 || index >= this.size) {
|
|
143
|
-
return { success: false, error: 'Index out of bounds' };
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const oldValue = this.data[index];
|
|
147
|
-
this.data[index] = value;
|
|
148
|
-
this.updateSegmentTree(0, index, value);
|
|
149
|
-
|
|
150
|
-
return { success: true, value: oldValue };
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Rebuilds the segment tree after major changes
|
|
155
|
-
*/
|
|
156
|
-
private rebuildSegmentTree(): void {
|
|
157
|
-
this.segmentTree = new Array(4 * this.capacity).fill(null);
|
|
158
|
-
if (this.size > 0) {
|
|
159
|
-
this.buildSegmentTree(0, 0, this.size - 1);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Builds a segment tree node recursively
|
|
165
|
-
*/
|
|
166
|
-
private buildSegmentTree(node: number, start: number, end: number): void {
|
|
167
|
-
if (start === end) {
|
|
168
|
-
this.segmentTree[node] = {
|
|
169
|
-
value: this.data[start] as T,
|
|
170
|
-
start,
|
|
171
|
-
end
|
|
172
|
-
};
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const mid = Math.floor((start + end) / 2);
|
|
177
|
-
this.buildSegmentTree(2 * node + 1, start, mid);
|
|
178
|
-
this.buildSegmentTree(2 * node + 2, mid + 1, end);
|
|
179
|
-
|
|
180
|
-
const leftNode = this.segmentTree[2 * node + 1];
|
|
181
|
-
const rightNode = this.segmentTree[2 * node + 2];
|
|
182
|
-
|
|
183
|
-
if (leftNode && rightNode) {
|
|
184
|
-
this.segmentTree[node] = {
|
|
185
|
-
value: this.comparator(leftNode.value, rightNode.value) >= 0
|
|
186
|
-
? leftNode.value
|
|
187
|
-
: rightNode.value,
|
|
188
|
-
start,
|
|
189
|
-
end
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Updates the segment tree after a value change
|
|
196
|
-
*/
|
|
197
|
-
private updateSegmentTree(node: number, index: number, value: T): void {
|
|
198
|
-
if (!this.segmentTree[node]) {
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const currentNode = this.segmentTree[node]!;
|
|
203
|
-
if (currentNode.start === currentNode.end) {
|
|
204
|
-
currentNode.value = value;
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const mid = Math.floor((currentNode.start + currentNode.end) / 2);
|
|
209
|
-
if (index <= mid) {
|
|
210
|
-
this.updateSegmentTree(2 * node + 1, index, value);
|
|
211
|
-
} else {
|
|
212
|
-
this.updateSegmentTree(2 * node + 2, index, value);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const leftNode = this.segmentTree[2 * node + 1];
|
|
216
|
-
const rightNode = this.segmentTree[2 * node + 2];
|
|
217
|
-
|
|
218
|
-
if (leftNode && rightNode) {
|
|
219
|
-
currentNode.value = this.comparator(leftNode.value, rightNode.value) >= 0
|
|
220
|
-
? leftNode.value
|
|
221
|
-
: rightNode.value;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Queries the maximum value in a range
|
|
227
|
-
*/
|
|
228
|
-
public queryRange(start: number, end: number): OperationResult<T> {
|
|
229
|
-
if (start < 0 || end >= this.size || start > end) {
|
|
230
|
-
return { success: false, error: 'Invalid range' };
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
const result = this.querySegmentTree(0, start, end);
|
|
234
|
-
return result
|
|
235
|
-
? { success: true, value: result }
|
|
236
|
-
: { success: false, error: 'Range query failed' };
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Recursively queries the segment tree
|
|
241
|
-
*/
|
|
242
|
-
private querySegmentTree(node: number, queryStart: number, queryEnd: number): T | null {
|
|
243
|
-
const currentNode = this.segmentTree[node];
|
|
244
|
-
if (!currentNode) {
|
|
245
|
-
return null;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (queryStart <= currentNode.start && queryEnd >= currentNode.end) {
|
|
249
|
-
return currentNode.value;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if (queryEnd < currentNode.start || queryStart > currentNode.end) {
|
|
253
|
-
return null;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
const leftResult = this.querySegmentTree(2 * node + 1, queryStart, queryEnd);
|
|
257
|
-
const rightResult = this.querySegmentTree(2 * node + 2, queryStart, queryEnd);
|
|
258
|
-
|
|
259
|
-
if (leftResult === null) return rightResult;
|
|
260
|
-
if (rightResult === null) return leftResult;
|
|
261
|
-
|
|
262
|
-
return this.comparator(leftResult, rightResult) >= 0 ? leftResult : rightResult;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Creates a heap from the current array
|
|
267
|
-
*/
|
|
268
|
-
public toHeap(isMin: boolean = true): MinHeap<T> | MaxHeap<T> {
|
|
269
|
-
const heap = isMin
|
|
270
|
-
? new MinHeap<T>(this.comparator)
|
|
271
|
-
: new MaxHeap<T>(this.comparator);
|
|
272
|
-
|
|
273
|
-
for (let i = 0; i < this.size; i++) {
|
|
274
|
-
if (this.data[i] !== undefined) {
|
|
275
|
-
if (this.data[i] !== undefined) {
|
|
276
|
-
heap.push(this.data[i] as T);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
return heap;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* Sorts the array in-place
|
|
286
|
-
*/
|
|
287
|
-
public sort(ascending: boolean = true): void {
|
|
288
|
-
const heap = this.toHeap(!ascending);
|
|
289
|
-
for (let i = this.size - 1; i >= 0; i--) {
|
|
290
|
-
const value = heap.pop();
|
|
291
|
-
if (value !== undefined) {
|
|
292
|
-
this.data[i] = value;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
this.rebuildSegmentTree();
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Returns array as native array
|
|
300
|
-
*/
|
|
301
|
-
public toArray(): T[] {
|
|
302
|
-
return this.data.slice(0, this.size);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
1
|
+
import { Comparator } from '@/core';
|
|
2
|
+
import { MinHeap, MaxHeap } from '../storage/Heap';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Interface for segment tree node operations
|
|
6
|
+
*/
|
|
7
|
+
export interface SegmentTreeNode<T> { value: T;
|
|
8
|
+
lazy?: T;
|
|
9
|
+
start: number;
|
|
10
|
+
end: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Type for BigArray operation result
|
|
15
|
+
*/
|
|
16
|
+
export type OperationResult<T> = {
|
|
17
|
+
success: boolean;
|
|
18
|
+
value?: T;
|
|
19
|
+
error?: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Options for BigArray initialization
|
|
24
|
+
*/
|
|
25
|
+
export interface BigArrayOptions<T> {
|
|
26
|
+
initialCapacity?: number;
|
|
27
|
+
growthFactor?: number;
|
|
28
|
+
comparator?: Comparator<T>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A specialized array implementation for handling large numbers and providing
|
|
33
|
+
* efficient operations with segment tree support
|
|
34
|
+
*/
|
|
35
|
+
export class BigArray<T> {
|
|
36
|
+
private data: T[];
|
|
37
|
+
private segmentTree: Array<SegmentTreeNode<T> | null>;
|
|
38
|
+
private readonly growthFactor: number;
|
|
39
|
+
private readonly comparator: Comparator<T>;
|
|
40
|
+
private size: number;
|
|
41
|
+
private capacity: number;
|
|
42
|
+
|
|
43
|
+
constructor(options: BigArrayOptions<T> = {}) {
|
|
44
|
+
const {
|
|
45
|
+
initialCapacity = 16,
|
|
46
|
+
growthFactor = 2,
|
|
47
|
+
comparator = ((a: T, b: T): -1 | 0 | 1 => {
|
|
48
|
+
if (a < b) return -1;
|
|
49
|
+
if (a > b) return 1;
|
|
50
|
+
return 0;
|
|
51
|
+
}) as Comparator<T>
|
|
52
|
+
} = options;
|
|
53
|
+
|
|
54
|
+
this.capacity = initialCapacity;
|
|
55
|
+
this.growthFactor = growthFactor;
|
|
56
|
+
this.comparator = comparator;
|
|
57
|
+
this.size = 0;
|
|
58
|
+
this.data = new Array(this.capacity);
|
|
59
|
+
this.segmentTree = new Array(4 * this.capacity).fill(null);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Gets the current size of the array
|
|
64
|
+
*/
|
|
65
|
+
public getSize(): number {
|
|
66
|
+
return this.size;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Gets the current capacity of the array
|
|
71
|
+
*/
|
|
72
|
+
public getCapacity(): number {
|
|
73
|
+
return this.capacity;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Resizes the internal array when needed
|
|
78
|
+
*/
|
|
79
|
+
private resize(newCapacity: number): void {
|
|
80
|
+
const newData = new Array(newCapacity);
|
|
81
|
+
for (let i = 0; i < this.size; i++) {
|
|
82
|
+
newData[i] = this.data[i];
|
|
83
|
+
}
|
|
84
|
+
this.data = newData;
|
|
85
|
+
this.capacity = newCapacity;
|
|
86
|
+
this.rebuildSegmentTree();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Appends an element to the end of the array
|
|
91
|
+
*/
|
|
92
|
+
public push(value: T): OperationResult<number> {
|
|
93
|
+
try {
|
|
94
|
+
if (this.size >= this.capacity) {
|
|
95
|
+
this.resize(this.capacity * this.growthFactor);
|
|
96
|
+
}
|
|
97
|
+
this.data[this.size] = value;
|
|
98
|
+
this.updateSegmentTree(0, this.size, value);
|
|
99
|
+
this.size++;
|
|
100
|
+
return { success: true, value: this.size - 1 };
|
|
101
|
+
} catch (error) {
|
|
102
|
+
return {
|
|
103
|
+
success: false,
|
|
104
|
+
error: error instanceof Error ? error.message : 'Unknown error during push'
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Removes and returns the last element
|
|
111
|
+
*/
|
|
112
|
+
public pop(): OperationResult<T> {
|
|
113
|
+
if (this.size === 0) {
|
|
114
|
+
return { success: false, error: 'Array is empty' };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const value = this.data[this.size - 1];
|
|
118
|
+
this.size--;
|
|
119
|
+
|
|
120
|
+
// Shrink array if it's too sparse
|
|
121
|
+
if (this.size < this.capacity / (this.growthFactor * 2)) {
|
|
122
|
+
this.resize(Math.max(16, Math.floor(this.capacity / this.growthFactor)));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return { success: true, value };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Gets element at specified index
|
|
130
|
+
*/
|
|
131
|
+
public get(index: number): OperationResult<T> {
|
|
132
|
+
if (index < 0 || index >= this.size) {
|
|
133
|
+
return { success: false, error: 'Index out of bounds' };
|
|
134
|
+
}
|
|
135
|
+
return { success: true, value: this.data[index] };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Sets element at specified index
|
|
140
|
+
*/
|
|
141
|
+
public set(index: number, value: T): OperationResult<T> {
|
|
142
|
+
if (index < 0 || index >= this.size) {
|
|
143
|
+
return { success: false, error: 'Index out of bounds' };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const oldValue = this.data[index];
|
|
147
|
+
this.data[index] = value;
|
|
148
|
+
this.updateSegmentTree(0, index, value);
|
|
149
|
+
|
|
150
|
+
return { success: true, value: oldValue };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Rebuilds the segment tree after major changes
|
|
155
|
+
*/
|
|
156
|
+
private rebuildSegmentTree(): void {
|
|
157
|
+
this.segmentTree = new Array(4 * this.capacity).fill(null);
|
|
158
|
+
if (this.size > 0) {
|
|
159
|
+
this.buildSegmentTree(0, 0, this.size - 1);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Builds a segment tree node recursively
|
|
165
|
+
*/
|
|
166
|
+
private buildSegmentTree(node: number, start: number, end: number): void {
|
|
167
|
+
if (start === end) {
|
|
168
|
+
this.segmentTree[node] = {
|
|
169
|
+
value: this.data[start] as T,
|
|
170
|
+
start,
|
|
171
|
+
end
|
|
172
|
+
};
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const mid = Math.floor((start + end) / 2);
|
|
177
|
+
this.buildSegmentTree(2 * node + 1, start, mid);
|
|
178
|
+
this.buildSegmentTree(2 * node + 2, mid + 1, end);
|
|
179
|
+
|
|
180
|
+
const leftNode = this.segmentTree[2 * node + 1];
|
|
181
|
+
const rightNode = this.segmentTree[2 * node + 2];
|
|
182
|
+
|
|
183
|
+
if (leftNode && rightNode) {
|
|
184
|
+
this.segmentTree[node] = {
|
|
185
|
+
value: this.comparator(leftNode.value, rightNode.value) >= 0
|
|
186
|
+
? leftNode.value
|
|
187
|
+
: rightNode.value,
|
|
188
|
+
start,
|
|
189
|
+
end
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Updates the segment tree after a value change
|
|
196
|
+
*/
|
|
197
|
+
private updateSegmentTree(node: number, index: number, value: T): void {
|
|
198
|
+
if (!this.segmentTree[node]) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const currentNode = this.segmentTree[node]!;
|
|
203
|
+
if (currentNode.start === currentNode.end) {
|
|
204
|
+
currentNode.value = value;
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const mid = Math.floor((currentNode.start + currentNode.end) / 2);
|
|
209
|
+
if (index <= mid) {
|
|
210
|
+
this.updateSegmentTree(2 * node + 1, index, value);
|
|
211
|
+
} else {
|
|
212
|
+
this.updateSegmentTree(2 * node + 2, index, value);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const leftNode = this.segmentTree[2 * node + 1];
|
|
216
|
+
const rightNode = this.segmentTree[2 * node + 2];
|
|
217
|
+
|
|
218
|
+
if (leftNode && rightNode) {
|
|
219
|
+
currentNode.value = this.comparator(leftNode.value, rightNode.value) >= 0
|
|
220
|
+
? leftNode.value
|
|
221
|
+
: rightNode.value;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Queries the maximum value in a range
|
|
227
|
+
*/
|
|
228
|
+
public queryRange(start: number, end: number): OperationResult<T> {
|
|
229
|
+
if (start < 0 || end >= this.size || start > end) {
|
|
230
|
+
return { success: false, error: 'Invalid range' };
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const result = this.querySegmentTree(0, start, end);
|
|
234
|
+
return result
|
|
235
|
+
? { success: true, value: result }
|
|
236
|
+
: { success: false, error: 'Range query failed' };
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Recursively queries the segment tree
|
|
241
|
+
*/
|
|
242
|
+
private querySegmentTree(node: number, queryStart: number, queryEnd: number): T | null {
|
|
243
|
+
const currentNode = this.segmentTree[node];
|
|
244
|
+
if (!currentNode) {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (queryStart <= currentNode.start && queryEnd >= currentNode.end) {
|
|
249
|
+
return currentNode.value;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (queryEnd < currentNode.start || queryStart > currentNode.end) {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const leftResult = this.querySegmentTree(2 * node + 1, queryStart, queryEnd);
|
|
257
|
+
const rightResult = this.querySegmentTree(2 * node + 2, queryStart, queryEnd);
|
|
258
|
+
|
|
259
|
+
if (leftResult === null) return rightResult;
|
|
260
|
+
if (rightResult === null) return leftResult;
|
|
261
|
+
|
|
262
|
+
return this.comparator(leftResult, rightResult) >= 0 ? leftResult : rightResult;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Creates a heap from the current array
|
|
267
|
+
*/
|
|
268
|
+
public toHeap(isMin: boolean = true): MinHeap<T> | MaxHeap<T> {
|
|
269
|
+
const heap = isMin
|
|
270
|
+
? new MinHeap<T>(this.comparator)
|
|
271
|
+
: new MaxHeap<T>(this.comparator);
|
|
272
|
+
|
|
273
|
+
for (let i = 0; i < this.size; i++) {
|
|
274
|
+
if (this.data[i] !== undefined) {
|
|
275
|
+
if (this.data[i] !== undefined) {
|
|
276
|
+
heap.push(this.data[i] as T);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return heap;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Sorts the array in-place
|
|
286
|
+
*/
|
|
287
|
+
public sort(ascending: boolean = true): void {
|
|
288
|
+
const heap = this.toHeap(!ascending);
|
|
289
|
+
for (let i = this.size - 1; i >= 0; i--) {
|
|
290
|
+
const value = heap.pop();
|
|
291
|
+
if (value !== undefined) {
|
|
292
|
+
this.data[i] = value;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
this.rebuildSegmentTree();
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Returns array as native array
|
|
300
|
+
*/
|
|
301
|
+
public toArray(): T[] {
|
|
302
|
+
return this.data.slice(0, this.size);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
306
|
export default BigArray;
|
package/src/structures/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AckermannStructure } from './ackermann';
|
|
2
|
-
export { BigArray, type BigArrayOptions } from './big-array';
|
|
3
|
-
export { NumberTree } from './number-tree';
|
|
1
|
+
export { AckermannStructure } from './ackermann';
|
|
2
|
+
export { BigArray, type BigArrayOptions } from './big-array';
|
|
3
|
+
export { NumberTree } from './number-tree';
|
|
4
4
|
export { PowerTower } from './power-tower';
|