@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.
Files changed (140) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +355 -256
  3. package/dist/index.cjs +4 -8
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.js +4 -7
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.umd.js +2 -2
  9. package/dist/index.umd.js.map +1 -1
  10. package/dist/types/{config → src/config}/config-loader.d.ts +0 -0
  11. package/dist/types/src/config/config-loader.d.ts.map +1 -0
  12. package/dist/types/{config → src/config}/config-parser.d.ts +0 -0
  13. package/dist/types/src/config/config-parser.d.ts.map +1 -0
  14. package/dist/types/{config → src/config}/config-resolver.d.ts +0 -0
  15. package/dist/types/src/config/config-resolver.d.ts.map +1 -0
  16. package/dist/types/{config → src/config}/config-source.d.ts +0 -0
  17. package/dist/types/src/config/config-source.d.ts.map +1 -0
  18. package/dist/types/{config → src/config}/index.d.ts +0 -0
  19. package/dist/types/src/config/index.d.ts.map +1 -0
  20. package/dist/types/{core → src/core}/common.d.ts +0 -0
  21. package/dist/types/src/core/common.d.ts.map +1 -0
  22. package/dist/types/{core → src/core}/config.d.ts +0 -0
  23. package/dist/types/src/core/config.d.ts.map +1 -0
  24. package/dist/types/{core → src/core}/constants.d.ts +0 -0
  25. package/dist/types/src/core/constants.d.ts.map +1 -0
  26. package/dist/types/{core → src/core}/errors.d.ts +0 -0
  27. package/dist/types/src/core/errors.d.ts.map +1 -0
  28. package/dist/types/{core → src/core}/hypernum.d.ts +0 -0
  29. package/dist/types/src/core/hypernum.d.ts.map +1 -0
  30. package/dist/types/{core → src/core}/index.d.ts +0 -0
  31. package/dist/types/src/core/index.d.ts.map +1 -0
  32. package/dist/types/{index.d.ts → src/index.d.ts} +1 -1
  33. package/dist/types/src/index.d.ts.map +1 -0
  34. package/dist/types/{operations → src/operations}/arithmetic.d.ts +0 -0
  35. package/dist/types/src/operations/arithmetic.d.ts.map +1 -0
  36. package/dist/types/{operations → src/operations}/bitwise.d.ts +0 -0
  37. package/dist/types/src/operations/bitwise.d.ts.map +1 -0
  38. package/dist/types/{operations → src/operations}/comparison.d.ts +0 -0
  39. package/dist/types/src/operations/comparison.d.ts.map +1 -0
  40. package/dist/types/{operations → src/operations}/conversion.d.ts +0 -0
  41. package/dist/types/src/operations/conversion.d.ts.map +1 -0
  42. package/dist/types/{operations → src/operations}/factorial.d.ts +0 -0
  43. package/dist/types/src/operations/factorial.d.ts.map +1 -0
  44. package/dist/types/{operations → src/operations}/index.d.ts +0 -0
  45. package/dist/types/src/operations/index.d.ts.map +1 -0
  46. package/dist/types/{operations → src/operations}/power.d.ts +0 -0
  47. package/dist/types/src/operations/power.d.ts.map +1 -0
  48. package/dist/types/{storage → src/storage}/Heap.d.ts +0 -0
  49. package/dist/types/src/storage/Heap.d.ts.map +1 -0
  50. package/dist/types/{storage → src/storage}/index.d.ts +0 -0
  51. package/dist/types/src/storage/index.d.ts.map +1 -0
  52. package/dist/types/{structures → src/structures}/ackermann.d.ts +0 -0
  53. package/dist/types/src/structures/ackermann.d.ts.map +1 -0
  54. package/dist/types/{structures → src/structures}/big-array.d.ts +0 -0
  55. package/dist/types/src/structures/big-array.d.ts.map +1 -0
  56. package/dist/types/{structures → src/structures}/index.d.ts +0 -0
  57. package/dist/types/src/structures/index.d.ts.map +1 -0
  58. package/dist/types/{structures → src/structures}/number-tree.d.ts +0 -0
  59. package/dist/types/src/structures/number-tree.d.ts.map +1 -0
  60. package/dist/types/{structures → src/structures}/power-tower.d.ts +0 -0
  61. package/dist/types/src/structures/power-tower.d.ts.map +1 -0
  62. package/dist/types/{utils → src/utils}/formatting.d.ts +0 -0
  63. package/dist/types/src/utils/formatting.d.ts.map +1 -0
  64. package/dist/types/{utils → src/utils}/index.d.ts +0 -0
  65. package/dist/types/src/utils/index.d.ts.map +1 -0
  66. package/dist/types/{utils → src/utils}/parser.d.ts +0 -0
  67. package/dist/types/src/utils/parser.d.ts.map +1 -0
  68. package/dist/types/{utils → src/utils}/precision.d.ts +0 -0
  69. package/dist/types/src/utils/precision.d.ts.map +1 -0
  70. package/dist/types/{utils → src/utils}/validation.d.ts +0 -0
  71. package/dist/types/src/utils/validation.d.ts.map +1 -0
  72. package/package.json +169 -164
  73. package/rollup.config.js +163 -161
  74. package/src/cli/hypernum.js +272 -0
  75. package/src/config/config-loader.ts +0 -0
  76. package/src/config/config-parser.ts +160 -160
  77. package/src/config/config-resolver.ts +0 -0
  78. package/src/config/config-source.ts +0 -0
  79. package/src/config/index.ts +0 -0
  80. package/src/core/common.ts +184 -184
  81. package/src/core/config.ts +392 -392
  82. package/src/core/constants.ts +101 -101
  83. package/src/core/errors.ts +202 -202
  84. package/src/core/hypernum.ts +240 -240
  85. package/src/core/index.ts +4 -4
  86. package/src/index.ts +179 -182
  87. package/src/operations/arithmetic.ts +332 -332
  88. package/src/operations/bitwise.ts +366 -366
  89. package/src/operations/comparison.ts +271 -271
  90. package/src/operations/conversion.ts +399 -399
  91. package/src/operations/factorial.ts +278 -278
  92. package/src/operations/index.ts +4 -4
  93. package/src/operations/power.ts +315 -315
  94. package/src/storage/Heap.ts +237 -237
  95. package/src/storage/index.ts +0 -0
  96. package/src/structures/ackermann.ts +232 -232
  97. package/src/structures/big-array.ts +305 -305
  98. package/src/structures/index.ts +3 -3
  99. package/src/structures/number-tree.ts +403 -403
  100. package/src/structures/power-tower.ts +277 -277
  101. package/src/types/common.d.ts +356 -356
  102. package/src/types/core.d.ts +160 -160
  103. package/src/types/index.d.ts +1 -1
  104. package/src/utils/formatting.ts +245 -245
  105. package/src/utils/index.ts +4 -4
  106. package/src/utils/parser.ts +244 -244
  107. package/src/utils/precision.ts +216 -216
  108. package/src/utils/validation.ts +182 -182
  109. package/tsconfig.json +83 -83
  110. package/dist/types/config/config-loader.d.ts.map +0 -1
  111. package/dist/types/config/config-parser.d.ts.map +0 -1
  112. package/dist/types/config/config-resolver.d.ts.map +0 -1
  113. package/dist/types/config/config-source.d.ts.map +0 -1
  114. package/dist/types/config/index.d.ts.map +0 -1
  115. package/dist/types/core/common.d.ts.map +0 -1
  116. package/dist/types/core/config.d.ts.map +0 -1
  117. package/dist/types/core/constants.d.ts.map +0 -1
  118. package/dist/types/core/errors.d.ts.map +0 -1
  119. package/dist/types/core/hypernum.d.ts.map +0 -1
  120. package/dist/types/core/index.d.ts.map +0 -1
  121. package/dist/types/index.d.ts.map +0 -1
  122. package/dist/types/operations/arithmetic.d.ts.map +0 -1
  123. package/dist/types/operations/bitwise.d.ts.map +0 -1
  124. package/dist/types/operations/comparison.d.ts.map +0 -1
  125. package/dist/types/operations/conversion.d.ts.map +0 -1
  126. package/dist/types/operations/factorial.d.ts.map +0 -1
  127. package/dist/types/operations/index.d.ts.map +0 -1
  128. package/dist/types/operations/power.d.ts.map +0 -1
  129. package/dist/types/storage/Heap.d.ts.map +0 -1
  130. package/dist/types/storage/index.d.ts.map +0 -1
  131. package/dist/types/structures/ackermann.d.ts.map +0 -1
  132. package/dist/types/structures/big-array.d.ts.map +0 -1
  133. package/dist/types/structures/index.d.ts.map +0 -1
  134. package/dist/types/structures/number-tree.d.ts.map +0 -1
  135. package/dist/types/structures/power-tower.d.ts.map +0 -1
  136. package/dist/types/utils/formatting.d.ts.map +0 -1
  137. package/dist/types/utils/index.d.ts.map +0 -1
  138. package/dist/types/utils/parser.d.ts.map +0 -1
  139. package/dist/types/utils/precision.d.ts.map +0 -1
  140. package/dist/types/utils/validation.d.ts.map +0 -1
@@ -1,404 +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
-
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
404
  export default NumberTree;