@obinexusmk2/hypernum 0.1.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.
Files changed (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +256 -0
  3. package/dist/index.cjs +3425 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.ts +1449 -0
  6. package/dist/index.js +3284 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/index.umd.js +8 -0
  9. package/dist/index.umd.js.map +1 -0
  10. package/dist/types/config/config-loader.d.ts +56 -0
  11. package/dist/types/config/config-loader.d.ts.map +1 -0
  12. package/dist/types/config/config-parser.d.ts +28 -0
  13. package/dist/types/config/config-parser.d.ts.map +1 -0
  14. package/dist/types/config/config-resolver.d.ts +21 -0
  15. package/dist/types/config/config-resolver.d.ts.map +1 -0
  16. package/dist/types/config/config-source.d.ts +27 -0
  17. package/dist/types/config/config-source.d.ts.map +1 -0
  18. package/dist/types/config/index.d.ts +68 -0
  19. package/dist/types/config/index.d.ts.map +1 -0
  20. package/dist/types/core/common.d.ts +169 -0
  21. package/dist/types/core/common.d.ts.map +1 -0
  22. package/dist/types/core/config.d.ts +197 -0
  23. package/dist/types/core/config.d.ts.map +1 -0
  24. package/dist/types/core/constants.d.ts +88 -0
  25. package/dist/types/core/constants.d.ts.map +1 -0
  26. package/dist/types/core/errors.d.ts +97 -0
  27. package/dist/types/core/errors.d.ts.map +1 -0
  28. package/dist/types/core/hypernum.d.ts +60 -0
  29. package/dist/types/core/hypernum.d.ts.map +1 -0
  30. package/dist/types/core/index.d.ts +6 -0
  31. package/dist/types/core/index.d.ts.map +1 -0
  32. package/dist/types/index.d.ts +33 -0
  33. package/dist/types/index.d.ts.map +1 -0
  34. package/dist/types/operations/arithmetic.d.ts +72 -0
  35. package/dist/types/operations/arithmetic.d.ts.map +1 -0
  36. package/dist/types/operations/bitwise.d.ts +98 -0
  37. package/dist/types/operations/bitwise.d.ts.map +1 -0
  38. package/dist/types/operations/comparison.d.ts +94 -0
  39. package/dist/types/operations/comparison.d.ts.map +1 -0
  40. package/dist/types/operations/conversion.d.ts +79 -0
  41. package/dist/types/operations/conversion.d.ts.map +1 -0
  42. package/dist/types/operations/factorial.d.ts +58 -0
  43. package/dist/types/operations/factorial.d.ts.map +1 -0
  44. package/dist/types/operations/index.d.ts +6 -0
  45. package/dist/types/operations/index.d.ts.map +1 -0
  46. package/dist/types/operations/power.d.ts +49 -0
  47. package/dist/types/operations/power.d.ts.map +1 -0
  48. package/dist/types/storage/Heap.d.ts +95 -0
  49. package/dist/types/storage/Heap.d.ts.map +1 -0
  50. package/dist/types/storage/index.d.ts +2 -0
  51. package/dist/types/storage/index.d.ts.map +1 -0
  52. package/dist/types/structures/ackermann.d.ts +74 -0
  53. package/dist/types/structures/ackermann.d.ts.map +1 -0
  54. package/dist/types/structures/big-array.d.ts +102 -0
  55. package/dist/types/structures/big-array.d.ts.map +1 -0
  56. package/dist/types/structures/index.d.ts +5 -0
  57. package/dist/types/structures/index.d.ts.map +1 -0
  58. package/dist/types/structures/number-tree.d.ts +114 -0
  59. package/dist/types/structures/number-tree.d.ts.map +1 -0
  60. package/dist/types/structures/power-tower.d.ts +74 -0
  61. package/dist/types/structures/power-tower.d.ts.map +1 -0
  62. package/dist/types/utils/formatting.d.ts +45 -0
  63. package/dist/types/utils/formatting.d.ts.map +1 -0
  64. package/dist/types/utils/index.d.ts +5 -0
  65. package/dist/types/utils/index.d.ts.map +1 -0
  66. package/dist/types/utils/parser.d.ts +39 -0
  67. package/dist/types/utils/parser.d.ts.map +1 -0
  68. package/dist/types/utils/precision.d.ts +57 -0
  69. package/dist/types/utils/precision.d.ts.map +1 -0
  70. package/dist/types/utils/validation.d.ts +28 -0
  71. package/dist/types/utils/validation.d.ts.map +1 -0
  72. package/package.json +164 -0
  73. package/rollup.config.js +162 -0
  74. package/src/config/config-loader.ts +226 -0
  75. package/src/config/config-parser.ts +161 -0
  76. package/src/config/config-resolver.ts +52 -0
  77. package/src/config/config-source.ts +32 -0
  78. package/src/config/index.ts +159 -0
  79. package/src/core/common.ts +185 -0
  80. package/src/core/config.ts +393 -0
  81. package/src/core/constants.ts +102 -0
  82. package/src/core/errors.ts +203 -0
  83. package/src/core/hypernum.ts +241 -0
  84. package/src/core/index.ts +5 -0
  85. package/src/index.ts +183 -0
  86. package/src/operations/arithmetic.ts +333 -0
  87. package/src/operations/bitwise.ts +367 -0
  88. package/src/operations/comparison.ts +272 -0
  89. package/src/operations/conversion.ts +400 -0
  90. package/src/operations/factorial.ts +279 -0
  91. package/src/operations/index.ts +5 -0
  92. package/src/operations/power.ts +316 -0
  93. package/src/storage/Heap.ts +238 -0
  94. package/src/storage/index.ts +1 -0
  95. package/src/structures/ackermann.ts +233 -0
  96. package/src/structures/big-array.ts +306 -0
  97. package/src/structures/index.ts +4 -0
  98. package/src/structures/number-tree.ts +404 -0
  99. package/src/structures/power-tower.ts +278 -0
  100. package/src/types/common.d.ts +357 -0
  101. package/src/types/core.d.ts +161 -0
  102. package/src/types/index.d.ts +2 -0
  103. package/src/utils/formatting.ts +246 -0
  104. package/src/utils/index.ts +4 -0
  105. package/src/utils/parser.ts +245 -0
  106. package/src/utils/precision.ts +217 -0
  107. package/src/utils/validation.ts +183 -0
  108. package/tsconfig.json +84 -0
@@ -0,0 +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
+
306
+ export default BigArray;
@@ -0,0 +1,4 @@
1
+ export { AckermannStructure } from './ackermann';
2
+ export { BigArray, type BigArrayOptions } from './big-array';
3
+ export { NumberTree } from './number-tree';
4
+ export { PowerTower } from './power-tower';
@@ -0,0 +1,404 @@
1
+ import { Comparator } from "@/core";
2
+
3
+ /**
4
+ * Interface for tree node statistics
5
+ */
6
+ interface NodeStats {
7
+ height: number;
8
+ size: number;
9
+ sum: bigint;
10
+ min: bigint;
11
+ max: bigint;
12
+ }
13
+
14
+ /**
15
+ * Interface for tree traversal configuration
16
+ */
17
+ interface TraversalConfig {
18
+ includeStats?: boolean;
19
+ skipSubtrees?: boolean;
20
+ maxDepth?: number;
21
+ }
22
+
23
+ /**
24
+ * Class representing a node in the number tree
25
+ */
26
+ class NumberNode {
27
+ value: bigint;
28
+ left: NumberNode | null;
29
+ right: NumberNode | null;
30
+ parent: NumberNode | null;
31
+ height: number;
32
+ size: number;
33
+ sum: bigint;
34
+
35
+ constructor(value: bigint | string | number) {
36
+ this.value = typeof value === 'bigint' ? value : BigInt(value);
37
+ this.left = null;
38
+ this.right = null;
39
+ this.parent = null;
40
+ this.height = 1;
41
+ this.size = 1;
42
+ this.sum = this.value;
43
+ }
44
+
45
+ /**
46
+ * Updates node statistics based on children
47
+ */
48
+ updateStats(): void {
49
+ this.height = 1 + Math.max(
50
+ this.left?.height ?? 0,
51
+ this.right?.height ?? 0
52
+ );
53
+ this.size = 1 + (this.left?.size ?? 0) + (this.right?.size ?? 0);
54
+ this.sum = this.value +
55
+ (this.left?.sum ?? BigInt(0)) +
56
+ (this.right?.sum ?? BigInt(0));
57
+ }
58
+
59
+ /**
60
+ * Gets balance factor of the node
61
+ */
62
+ getBalance(): number {
63
+ return (this.left?.height ?? 0) - (this.right?.height ?? 0);
64
+ }
65
+
66
+ /**
67
+ * Gets complete statistics for the node and its subtree
68
+ */
69
+ getStats(): NodeStats {
70
+ return {
71
+ height: this.height,
72
+ size: this.size,
73
+ sum: this.sum,
74
+ min: this.findMin().value,
75
+ max: this.findMax().value
76
+ };
77
+ }
78
+
79
+ /**
80
+ * Finds minimum value node in the subtree
81
+ */
82
+ findMin(): NumberNode {
83
+ let current: NumberNode = this;
84
+ while (current.left) {
85
+ current = current.left;
86
+ }
87
+ return current;
88
+ }
89
+
90
+ /**
91
+ * Finds maximum value node in the subtree
92
+ */
93
+ findMax(): NumberNode {
94
+ let current: NumberNode = this;
95
+ while (current.right) {
96
+ current = current.right;
97
+ }
98
+ return current;
99
+ }
100
+ }
101
+
102
+ /**
103
+ * AVL Tree implementation specialized for handling large numbers
104
+ */
105
+ export class NumberTree {
106
+ private root: NumberNode | null;
107
+ private readonly comparator: Comparator<bigint>;
108
+
109
+ constructor(comparator?: Comparator<bigint>) {
110
+ this.root = null;
111
+ this.comparator = comparator ?? ((a: bigint, b: bigint): -1 | 0 | 1 => {
112
+ if (a < b) return -1;
113
+ if (a > b) return 1;
114
+ return 0;
115
+ });
116
+ }
117
+
118
+ /**
119
+ * Gets the root node if it exists
120
+ */
121
+ public getRoot(): NumberNode | null {
122
+ return this.root;
123
+ }
124
+
125
+ /**
126
+ * Inserts a new value into the tree
127
+ */
128
+ public insert(value: bigint | string | number): NumberNode {
129
+ const newValue = typeof value === 'bigint' ? value : BigInt(value);
130
+ this.root = this.insertNode(this.root, newValue);
131
+ return this.find(newValue)!;
132
+ }
133
+
134
+ /**
135
+ * Recursively inserts a new node
136
+ */
137
+ private insertNode(node: NumberNode | null, value: bigint): NumberNode {
138
+ if (!node) {
139
+ return new NumberNode(value);
140
+ }
141
+
142
+ const compareResult = this.comparator(value, node.value);
143
+ if (compareResult < 0) {
144
+ node.left = this.insertNode(node.left, value);
145
+ node.left.parent = node;
146
+ } else if (compareResult > 0) {
147
+ node.right = this.insertNode(node.right, value);
148
+ node.right.parent = node;
149
+ } else {
150
+ return node; // Duplicate value, return existing node
151
+ }
152
+
153
+ node.updateStats();
154
+ return this.balance(node);
155
+ }
156
+
157
+ /**
158
+ * Balances a node using AVL rotations
159
+ */
160
+ private balance(node: NumberNode): NumberNode {
161
+ const balance = node.getBalance();
162
+
163
+ // Left heavy
164
+ if (balance > 1) {
165
+ if (node.left && node.left.getBalance() < 0) {
166
+ node.left = this.rotateLeft(node.left);
167
+ }
168
+ return this.rotateRight(node);
169
+ }
170
+
171
+ // Right heavy
172
+ if (balance < -1) {
173
+ if (node.right && node.right.getBalance() > 0) {
174
+ node.right = this.rotateRight(node.right);
175
+ }
176
+ return this.rotateLeft(node);
177
+ }
178
+
179
+ return node;
180
+ }
181
+
182
+ /**
183
+ * Performs left rotation
184
+ */
185
+ private rotateLeft(node: NumberNode): NumberNode {
186
+ const rightChild = node.right!;
187
+ const rightLeftChild = rightChild.left;
188
+
189
+ rightChild.left = node;
190
+ node.right = rightLeftChild;
191
+
192
+ if (rightLeftChild) {
193
+ rightLeftChild.parent = node;
194
+ }
195
+ rightChild.parent = node.parent;
196
+ node.parent = rightChild;
197
+
198
+ node.updateStats();
199
+ rightChild.updateStats();
200
+
201
+ return rightChild;
202
+ }
203
+
204
+ /**
205
+ * Performs right rotation
206
+ */
207
+ private rotateRight(node: NumberNode): NumberNode {
208
+ const leftChild = node.left!;
209
+ const leftRightChild = leftChild.right;
210
+
211
+ leftChild.right = node;
212
+ node.left = leftRightChild;
213
+
214
+ if (leftRightChild) {
215
+ leftRightChild.parent = node;
216
+ }
217
+ leftChild.parent = node.parent;
218
+ node.parent = leftChild;
219
+
220
+ node.updateStats();
221
+ leftChild.updateStats();
222
+
223
+ return leftChild;
224
+ }
225
+
226
+ /**
227
+ * Removes a value from the tree
228
+ */
229
+ public remove(value: bigint | string | number): boolean {
230
+ const searchValue = typeof value === 'bigint' ? value : BigInt(value);
231
+ const nodeToRemove = this.find(searchValue);
232
+
233
+ if (!nodeToRemove) {
234
+ return false;
235
+ }
236
+
237
+ this.root = this.removeNode(this.root, searchValue);
238
+ return true;
239
+ }
240
+
241
+ /**
242
+ * Recursively removes a node
243
+ */
244
+ private removeNode(node: NumberNode | null, value: bigint): NumberNode | null {
245
+ if (!node) {
246
+ return null;
247
+ }
248
+
249
+ const compareResult = this.comparator(value, node.value);
250
+ if (compareResult < 0) {
251
+ node.left = this.removeNode(node.left, value);
252
+ if (node.left) {
253
+ node.left.parent = node;
254
+ }
255
+ } else if (compareResult > 0) {
256
+ node.right = this.removeNode(node.right, value);
257
+ if (node.right) {
258
+ node.right.parent = node;
259
+ }
260
+ } else {
261
+ // Node to delete found
262
+ if (!node.left) {
263
+ return node.right;
264
+ }
265
+ if (!node.right) {
266
+ return node.left;
267
+ }
268
+
269
+ // Node has two children
270
+ const successor = node.right.findMin();
271
+ node.value = successor.value;
272
+ node.right = this.removeNode(node.right, successor.value);
273
+ if (node.right) {
274
+ node.right.parent = node;
275
+ }
276
+ }
277
+
278
+ node.updateStats();
279
+ return this.balance(node);
280
+ }
281
+
282
+ /**
283
+ * Finds a node by value
284
+ */
285
+ public find(value: bigint | string | number): NumberNode | null {
286
+ const searchValue = typeof value === 'bigint' ? value : BigInt(value);
287
+ let current = this.root;
288
+
289
+ while (current) {
290
+ const compareResult = this.comparator(searchValue, current.value);
291
+ if (compareResult === 0) {
292
+ return current;
293
+ }
294
+ current = compareResult < 0 ? current.left : current.right;
295
+ }
296
+
297
+ return null;
298
+ }
299
+
300
+ /**
301
+ * Traverses the tree in specified order and returns values
302
+ */
303
+ public traverse(order: 'inOrder' | 'preOrder' | 'postOrder' = 'inOrder',
304
+ config: TraversalConfig = {}): bigint[] {
305
+ const result: bigint[] = [];
306
+
307
+ const traverse = (node: NumberNode | null, depth: number = 0): void => {
308
+ if (!node || (config.maxDepth !== undefined && depth >= config.maxDepth)) {
309
+ return;
310
+ }
311
+
312
+ if (order === 'preOrder') {
313
+ result.push(node.value);
314
+ }
315
+
316
+ if (!config.skipSubtrees) {
317
+ traverse(node.left, depth + 1);
318
+ }
319
+
320
+ if (order === 'inOrder') {
321
+ result.push(node.value);
322
+ }
323
+
324
+ if (!config.skipSubtrees) {
325
+ traverse(node.right, depth + 1);
326
+ }
327
+
328
+ if (order === 'postOrder') {
329
+ result.push(node.value);
330
+ }
331
+ };
332
+
333
+ traverse(this.root);
334
+ return result;
335
+ }
336
+
337
+ /**
338
+ * Gets overall tree statistics
339
+ */
340
+ public getTreeStats(): NodeStats | null {
341
+ return this.root?.getStats() ?? null;
342
+ }
343
+
344
+ /**
345
+ * Gets the nth smallest value in the tree
346
+ */
347
+ public getNthValue(n: number): bigint | null {
348
+ if (!this.root || n < 1 || n > this.root.size) {
349
+ return null;
350
+ }
351
+
352
+ const findNth = (node: NumberNode | null, position: number): bigint | null => {
353
+ if (!node) {
354
+ return null;
355
+ }
356
+
357
+ const leftSize = node.left?.size ?? 0;
358
+
359
+ if (position === leftSize + 1) {
360
+ return node.value;
361
+ }
362
+
363
+ if (position <= leftSize) {
364
+ return findNth(node.left, position);
365
+ }
366
+
367
+ return findNth(node.right, position - leftSize - 1);
368
+ };
369
+
370
+ return findNth(this.root, n);
371
+ }
372
+
373
+ /**
374
+ * Gets a range of values between start and end (inclusive)
375
+ */
376
+ public getRange(start: bigint | string | number,
377
+ end: bigint | string | number): bigint[] {
378
+ const startValue = typeof start === 'bigint' ? start : BigInt(start);
379
+ const endValue = typeof end === 'bigint' ? end : BigInt(end);
380
+ const result: bigint[] = [];
381
+
382
+ const collectRange = (node: NumberNode | null): void => {
383
+ if (!node) {
384
+ return;
385
+ }
386
+
387
+ if (this.comparator(node.value, startValue) >= 0 &&
388
+ this.comparator(node.value, endValue) <= 0) {
389
+ collectRange(node.left);
390
+ result.push(node.value);
391
+ collectRange(node.right);
392
+ } else if (this.comparator(node.value, startValue) > 0) {
393
+ collectRange(node.left);
394
+ } else {
395
+ collectRange(node.right);
396
+ }
397
+ };
398
+
399
+ collectRange(this.root);
400
+ return result;
401
+ }
402
+ }
403
+
404
+ export default NumberTree;