@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,278 +1,278 @@
|
|
|
1
|
-
import { validateNonNegative, ValidationError, OverflowError } from '../utils/validation';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Interface for power tower computation options
|
|
5
|
-
*/
|
|
6
|
-
interface PowerTowerOptions {
|
|
7
|
-
maxHeight?: number;
|
|
8
|
-
maxValue?: bigint;
|
|
9
|
-
checkOverflow?: boolean;
|
|
10
|
-
precision?: number;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Interface for power tower node to track computation state
|
|
15
|
-
*/
|
|
16
|
-
interface PowerTowerNode {
|
|
17
|
-
value: bigint;
|
|
18
|
-
height: number;
|
|
19
|
-
evaluated: boolean;
|
|
20
|
-
previous: PowerTowerNode | null;
|
|
21
|
-
next: PowerTowerNode | null;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Default options for power tower computations
|
|
26
|
-
*/
|
|
27
|
-
const DEFAULT_OPTIONS: Required<PowerTowerOptions> = {
|
|
28
|
-
maxHeight: 100,
|
|
29
|
-
maxValue: BigInt(Number.MAX_SAFE_INTEGER),
|
|
30
|
-
checkOverflow: true,
|
|
31
|
-
precision: 0
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Class representing a power tower (tetration) computation structure
|
|
36
|
-
* Handles expressions of the form: a↑↑b = a^(a^(a^...)) (b times)
|
|
37
|
-
*/
|
|
38
|
-
export class PowerTower {
|
|
39
|
-
private readonly options: Required<PowerTowerOptions>;
|
|
40
|
-
private head: PowerTowerNode | null;
|
|
41
|
-
private tail: PowerTowerNode | null;
|
|
42
|
-
private size: number;
|
|
43
|
-
|
|
44
|
-
constructor(options: PowerTowerOptions = {}) {
|
|
45
|
-
this.options = { ...DEFAULT_OPTIONS, ...options };
|
|
46
|
-
this.head = null;
|
|
47
|
-
this.tail = null;
|
|
48
|
-
this.size = 0;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Creates a new power tower node
|
|
53
|
-
*/
|
|
54
|
-
private createNode(value: bigint, height: number): PowerTowerNode {
|
|
55
|
-
return {
|
|
56
|
-
value,
|
|
57
|
-
height,
|
|
58
|
-
evaluated: false,
|
|
59
|
-
previous: null,
|
|
60
|
-
next: null
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Validates power tower height
|
|
66
|
-
*/
|
|
67
|
-
private validateHeight(height: number): void {
|
|
68
|
-
if (height < 0) {
|
|
69
|
-
throw new ValidationError('Height cannot be negative');
|
|
70
|
-
}
|
|
71
|
-
if (height > this.options.maxHeight) {
|
|
72
|
-
throw new ValidationError(`Height exceeds maximum of ${this.options.maxHeight}`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Validates value for computation
|
|
78
|
-
*/
|
|
79
|
-
private validateValue(value: bigint): void {
|
|
80
|
-
validateNonNegative(value);
|
|
81
|
-
if (this.options.checkOverflow && value > this.options.maxValue) {
|
|
82
|
-
throw new OverflowError(`Value exceeds maximum of ${this.options.maxValue}`);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Computes power with overflow checking
|
|
88
|
-
*/
|
|
89
|
-
private computePower(base: bigint, exponent: bigint): bigint {
|
|
90
|
-
if (exponent === BigInt(0)) {
|
|
91
|
-
return BigInt(1);
|
|
92
|
-
}
|
|
93
|
-
if (exponent === BigInt(1)) {
|
|
94
|
-
return base;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
let result = base;
|
|
98
|
-
for (let i = BigInt(1); i < exponent; i++) {
|
|
99
|
-
if (this.options.checkOverflow) {
|
|
100
|
-
// Check if next multiplication would overflow
|
|
101
|
-
const next = result * base;
|
|
102
|
-
if (next > this.options.maxValue) {
|
|
103
|
-
throw new OverflowError('Power computation would overflow');
|
|
104
|
-
}
|
|
105
|
-
result = next;
|
|
106
|
-
} else {
|
|
107
|
-
result *= base;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
return result;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Builds a power tower of specified height with given base
|
|
115
|
-
*/
|
|
116
|
-
public build(base: bigint | number | string, height: number): void {
|
|
117
|
-
this.validateHeight(height);
|
|
118
|
-
const baseValue = typeof base === 'bigint' ? base : BigInt(base);
|
|
119
|
-
this.validateValue(baseValue);
|
|
120
|
-
|
|
121
|
-
this.clear(); // Clear existing tower
|
|
122
|
-
|
|
123
|
-
for (let i = 0; i < height; i++) {
|
|
124
|
-
const node = this.createNode(baseValue, i + 1);
|
|
125
|
-
if (!this.head) {
|
|
126
|
-
this.head = node;
|
|
127
|
-
this.tail = node;
|
|
128
|
-
} else {
|
|
129
|
-
node.previous = this.tail;
|
|
130
|
-
this.tail!.next = node;
|
|
131
|
-
this.tail = node;
|
|
132
|
-
}
|
|
133
|
-
this.size++;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Evaluates the power tower up to specified height
|
|
139
|
-
*/
|
|
140
|
-
public evaluate(height?: number): bigint {
|
|
141
|
-
if (!this.head) {
|
|
142
|
-
return BigInt(1); // Empty tower evaluates to 1
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const targetHeight = height ?? this.size;
|
|
146
|
-
this.validateHeight(targetHeight);
|
|
147
|
-
|
|
148
|
-
let current = this.head;
|
|
149
|
-
let result = current.value;
|
|
150
|
-
let currentHeight = 1;
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
while (current.next && currentHeight < targetHeight) {
|
|
154
|
-
result = this.computePower(current.next.value, result);
|
|
155
|
-
current.evaluated = true;
|
|
156
|
-
current = current.next;
|
|
157
|
-
currentHeight++;
|
|
158
|
-
}
|
|
159
|
-
current.evaluated = true;
|
|
160
|
-
return result;
|
|
161
|
-
} catch (error) {
|
|
162
|
-
if (error instanceof OverflowError) {
|
|
163
|
-
// Mark nodes up to current height as evaluated
|
|
164
|
-
let node = this.head;
|
|
165
|
-
while (node !== current) {
|
|
166
|
-
node.evaluated = true;
|
|
167
|
-
node = node.next!;
|
|
168
|
-
}
|
|
169
|
-
throw error;
|
|
170
|
-
}
|
|
171
|
-
throw error;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Gets the current height of the power tower
|
|
177
|
-
*/
|
|
178
|
-
public getHeight(): number {
|
|
179
|
-
return this.size;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Checks if the tower can be evaluated to a given height
|
|
184
|
-
*/
|
|
185
|
-
public isComputable(height?: number): boolean {
|
|
186
|
-
try {
|
|
187
|
-
const targetHeight = height ?? this.size;
|
|
188
|
-
this.validateHeight(targetHeight);
|
|
189
|
-
|
|
190
|
-
// Check first few levels without full computation
|
|
191
|
-
let current = this.head;
|
|
192
|
-
let currentHeight = 0;
|
|
193
|
-
|
|
194
|
-
while (current && currentHeight < targetHeight) {
|
|
195
|
-
// Quick check for obvious overflow conditions
|
|
196
|
-
if (current.value > BigInt(4) && currentHeight > 3) {
|
|
197
|
-
return false;
|
|
198
|
-
}
|
|
199
|
-
current = current.next;
|
|
200
|
-
currentHeight++;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// Try actual computation with a lower overflow threshold
|
|
204
|
-
const safeOptions = { ...this.options, maxValue: this.options.maxValue >> BigInt(1) };
|
|
205
|
-
const safeTower = new PowerTower(safeOptions);
|
|
206
|
-
safeTower.build(this.head!.value, targetHeight);
|
|
207
|
-
safeTower.evaluate();
|
|
208
|
-
|
|
209
|
-
return true;
|
|
210
|
-
} catch {
|
|
211
|
-
return false;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Gets the computation state at each level
|
|
217
|
-
*/
|
|
218
|
-
public getState(): { height: number; value: bigint; evaluated: boolean }[] {
|
|
219
|
-
const state = [];
|
|
220
|
-
let current = this.head;
|
|
221
|
-
|
|
222
|
-
while (current) {
|
|
223
|
-
state.push({
|
|
224
|
-
height: current.height,
|
|
225
|
-
value: current.value,
|
|
226
|
-
evaluated: current.evaluated
|
|
227
|
-
});
|
|
228
|
-
current = current.next;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return state;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Clears the power tower
|
|
236
|
-
*/
|
|
237
|
-
public clear(): void {
|
|
238
|
-
this.head = null;
|
|
239
|
-
this.tail = null;
|
|
240
|
-
this.size = 0;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Gets the maximum computationally feasible height for a given base
|
|
245
|
-
*/
|
|
246
|
-
public static getMaxFeasibleHeight(base: bigint | number | string): number {
|
|
247
|
-
const baseValue = typeof base === 'bigint' ? base : BigInt(base);
|
|
248
|
-
validateNonNegative(baseValue);
|
|
249
|
-
|
|
250
|
-
if (baseValue === BigInt(0)) return 0;
|
|
251
|
-
if (baseValue === BigInt(1)) return Infinity;
|
|
252
|
-
if (baseValue === BigInt(2)) return 4; // 2↑↑4 is already enormous
|
|
253
|
-
if (baseValue === BigInt(3)) return 3; // 3↑↑3 is already astronomical
|
|
254
|
-
if (baseValue === BigInt(4)) return 2;
|
|
255
|
-
return 1; // For bases > 4, only height 1 is reliably computable
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Creates a string representation of the power tower
|
|
260
|
-
*/
|
|
261
|
-
public toString(): string {
|
|
262
|
-
if (!this.head) {
|
|
263
|
-
return "Empty Tower";
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
let result = this.head.value.toString();
|
|
267
|
-
let current = this.head;
|
|
268
|
-
|
|
269
|
-
while (current.next) {
|
|
270
|
-
result = `${current.next.value}^(${result})`;
|
|
271
|
-
current = current.next;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return result;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
1
|
+
import { validateNonNegative, ValidationError, OverflowError } from '../utils/validation';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Interface for power tower computation options
|
|
5
|
+
*/
|
|
6
|
+
interface PowerTowerOptions {
|
|
7
|
+
maxHeight?: number;
|
|
8
|
+
maxValue?: bigint;
|
|
9
|
+
checkOverflow?: boolean;
|
|
10
|
+
precision?: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Interface for power tower node to track computation state
|
|
15
|
+
*/
|
|
16
|
+
interface PowerTowerNode {
|
|
17
|
+
value: bigint;
|
|
18
|
+
height: number;
|
|
19
|
+
evaluated: boolean;
|
|
20
|
+
previous: PowerTowerNode | null;
|
|
21
|
+
next: PowerTowerNode | null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Default options for power tower computations
|
|
26
|
+
*/
|
|
27
|
+
const DEFAULT_OPTIONS: Required<PowerTowerOptions> = {
|
|
28
|
+
maxHeight: 100,
|
|
29
|
+
maxValue: BigInt(Number.MAX_SAFE_INTEGER),
|
|
30
|
+
checkOverflow: true,
|
|
31
|
+
precision: 0
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Class representing a power tower (tetration) computation structure
|
|
36
|
+
* Handles expressions of the form: a↑↑b = a^(a^(a^...)) (b times)
|
|
37
|
+
*/
|
|
38
|
+
export class PowerTower {
|
|
39
|
+
private readonly options: Required<PowerTowerOptions>;
|
|
40
|
+
private head: PowerTowerNode | null;
|
|
41
|
+
private tail: PowerTowerNode | null;
|
|
42
|
+
private size: number;
|
|
43
|
+
|
|
44
|
+
constructor(options: PowerTowerOptions = {}) {
|
|
45
|
+
this.options = { ...DEFAULT_OPTIONS, ...options };
|
|
46
|
+
this.head = null;
|
|
47
|
+
this.tail = null;
|
|
48
|
+
this.size = 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Creates a new power tower node
|
|
53
|
+
*/
|
|
54
|
+
private createNode(value: bigint, height: number): PowerTowerNode {
|
|
55
|
+
return {
|
|
56
|
+
value,
|
|
57
|
+
height,
|
|
58
|
+
evaluated: false,
|
|
59
|
+
previous: null,
|
|
60
|
+
next: null
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Validates power tower height
|
|
66
|
+
*/
|
|
67
|
+
private validateHeight(height: number): void {
|
|
68
|
+
if (height < 0) {
|
|
69
|
+
throw new ValidationError('Height cannot be negative');
|
|
70
|
+
}
|
|
71
|
+
if (height > this.options.maxHeight) {
|
|
72
|
+
throw new ValidationError(`Height exceeds maximum of ${this.options.maxHeight}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Validates value for computation
|
|
78
|
+
*/
|
|
79
|
+
private validateValue(value: bigint): void {
|
|
80
|
+
validateNonNegative(value);
|
|
81
|
+
if (this.options.checkOverflow && value > this.options.maxValue) {
|
|
82
|
+
throw new OverflowError(`Value exceeds maximum of ${this.options.maxValue}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Computes power with overflow checking
|
|
88
|
+
*/
|
|
89
|
+
private computePower(base: bigint, exponent: bigint): bigint {
|
|
90
|
+
if (exponent === BigInt(0)) {
|
|
91
|
+
return BigInt(1);
|
|
92
|
+
}
|
|
93
|
+
if (exponent === BigInt(1)) {
|
|
94
|
+
return base;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
let result = base;
|
|
98
|
+
for (let i = BigInt(1); i < exponent; i++) {
|
|
99
|
+
if (this.options.checkOverflow) {
|
|
100
|
+
// Check if next multiplication would overflow
|
|
101
|
+
const next = result * base;
|
|
102
|
+
if (next > this.options.maxValue) {
|
|
103
|
+
throw new OverflowError('Power computation would overflow');
|
|
104
|
+
}
|
|
105
|
+
result = next;
|
|
106
|
+
} else {
|
|
107
|
+
result *= base;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Builds a power tower of specified height with given base
|
|
115
|
+
*/
|
|
116
|
+
public build(base: bigint | number | string, height: number): void {
|
|
117
|
+
this.validateHeight(height);
|
|
118
|
+
const baseValue = typeof base === 'bigint' ? base : BigInt(base);
|
|
119
|
+
this.validateValue(baseValue);
|
|
120
|
+
|
|
121
|
+
this.clear(); // Clear existing tower
|
|
122
|
+
|
|
123
|
+
for (let i = 0; i < height; i++) {
|
|
124
|
+
const node = this.createNode(baseValue, i + 1);
|
|
125
|
+
if (!this.head) {
|
|
126
|
+
this.head = node;
|
|
127
|
+
this.tail = node;
|
|
128
|
+
} else {
|
|
129
|
+
node.previous = this.tail;
|
|
130
|
+
this.tail!.next = node;
|
|
131
|
+
this.tail = node;
|
|
132
|
+
}
|
|
133
|
+
this.size++;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Evaluates the power tower up to specified height
|
|
139
|
+
*/
|
|
140
|
+
public evaluate(height?: number): bigint {
|
|
141
|
+
if (!this.head) {
|
|
142
|
+
return BigInt(1); // Empty tower evaluates to 1
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const targetHeight = height ?? this.size;
|
|
146
|
+
this.validateHeight(targetHeight);
|
|
147
|
+
|
|
148
|
+
let current = this.head;
|
|
149
|
+
let result = current.value;
|
|
150
|
+
let currentHeight = 1;
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
while (current.next && currentHeight < targetHeight) {
|
|
154
|
+
result = this.computePower(current.next.value, result);
|
|
155
|
+
current.evaluated = true;
|
|
156
|
+
current = current.next;
|
|
157
|
+
currentHeight++;
|
|
158
|
+
}
|
|
159
|
+
current.evaluated = true;
|
|
160
|
+
return result;
|
|
161
|
+
} catch (error) {
|
|
162
|
+
if (error instanceof OverflowError) {
|
|
163
|
+
// Mark nodes up to current height as evaluated
|
|
164
|
+
let node = this.head;
|
|
165
|
+
while (node !== current) {
|
|
166
|
+
node.evaluated = true;
|
|
167
|
+
node = node.next!;
|
|
168
|
+
}
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Gets the current height of the power tower
|
|
177
|
+
*/
|
|
178
|
+
public getHeight(): number {
|
|
179
|
+
return this.size;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Checks if the tower can be evaluated to a given height
|
|
184
|
+
*/
|
|
185
|
+
public isComputable(height?: number): boolean {
|
|
186
|
+
try {
|
|
187
|
+
const targetHeight = height ?? this.size;
|
|
188
|
+
this.validateHeight(targetHeight);
|
|
189
|
+
|
|
190
|
+
// Check first few levels without full computation
|
|
191
|
+
let current = this.head;
|
|
192
|
+
let currentHeight = 0;
|
|
193
|
+
|
|
194
|
+
while (current && currentHeight < targetHeight) {
|
|
195
|
+
// Quick check for obvious overflow conditions
|
|
196
|
+
if (current.value > BigInt(4) && currentHeight > 3) {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
current = current.next;
|
|
200
|
+
currentHeight++;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Try actual computation with a lower overflow threshold
|
|
204
|
+
const safeOptions = { ...this.options, maxValue: this.options.maxValue >> BigInt(1) };
|
|
205
|
+
const safeTower = new PowerTower(safeOptions);
|
|
206
|
+
safeTower.build(this.head!.value, targetHeight);
|
|
207
|
+
safeTower.evaluate();
|
|
208
|
+
|
|
209
|
+
return true;
|
|
210
|
+
} catch {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Gets the computation state at each level
|
|
217
|
+
*/
|
|
218
|
+
public getState(): { height: number; value: bigint; evaluated: boolean }[] {
|
|
219
|
+
const state = [];
|
|
220
|
+
let current = this.head;
|
|
221
|
+
|
|
222
|
+
while (current) {
|
|
223
|
+
state.push({
|
|
224
|
+
height: current.height,
|
|
225
|
+
value: current.value,
|
|
226
|
+
evaluated: current.evaluated
|
|
227
|
+
});
|
|
228
|
+
current = current.next;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return state;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Clears the power tower
|
|
236
|
+
*/
|
|
237
|
+
public clear(): void {
|
|
238
|
+
this.head = null;
|
|
239
|
+
this.tail = null;
|
|
240
|
+
this.size = 0;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Gets the maximum computationally feasible height for a given base
|
|
245
|
+
*/
|
|
246
|
+
public static getMaxFeasibleHeight(base: bigint | number | string): number {
|
|
247
|
+
const baseValue = typeof base === 'bigint' ? base : BigInt(base);
|
|
248
|
+
validateNonNegative(baseValue);
|
|
249
|
+
|
|
250
|
+
if (baseValue === BigInt(0)) return 0;
|
|
251
|
+
if (baseValue === BigInt(1)) return Infinity;
|
|
252
|
+
if (baseValue === BigInt(2)) return 4; // 2↑↑4 is already enormous
|
|
253
|
+
if (baseValue === BigInt(3)) return 3; // 3↑↑3 is already astronomical
|
|
254
|
+
if (baseValue === BigInt(4)) return 2;
|
|
255
|
+
return 1; // For bases > 4, only height 1 is reliably computable
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Creates a string representation of the power tower
|
|
260
|
+
*/
|
|
261
|
+
public toString(): string {
|
|
262
|
+
if (!this.head) {
|
|
263
|
+
return "Empty Tower";
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
let result = this.head.value.toString();
|
|
267
|
+
let current = this.head;
|
|
268
|
+
|
|
269
|
+
while (current.next) {
|
|
270
|
+
result = `${current.next.value}^(${result})`;
|
|
271
|
+
current = current.next;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return result;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
278
|
export default PowerTower;
|