-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfastGrowing.ts
101 lines (96 loc) · 2.35 KB
/
fastGrowing.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { Conway, type Conway0, type Ord0 } from "./conway";
import { unit } from "./op";
import { eq, isOne, isZero } from "./op";
import { canon, isLimit, pred } from "./op/ordinal";
import { type Real, realToBigint, realZero } from "./real";
/**
* Evaluates the Wainer hierarchy function.
* @param ord The ordinal number alpha
* @param n The natural number in `bigint`
* @returns The result in `bigint`
*/
export const wainer = (ord: Ord0, n: bigint): bigint => {
if (isZero(ord)) {
return n + 1n;
}
if (isLimit(ord)) {
return wainer(canon(ord, n), n);
}
let iter = 0n;
const o1 = pred(ord);
for (let i = 0n; i < n; i += 1n) {
iter = wainer(o1, n);
}
return iter;
};
/**
* Evaluates the Hardy hierarchy function.
* @param ord The ordinal number alpha
* @param n The natural number in `bigint`
* @returns The result in `bigint`
*/
export const hardy = (ord: Ord0, n: bigint): bigint => {
// console.log('hardy', ord, n);
if (isZero(ord)) {
return n;
}
// Closed form solutions
if (ord instanceof Conway) {
if (eq(ord, unit)) {
return 2n * n;
}
if (ord.length === 1) {
if (isOne(ord.leadingPower ?? 0)) {
const a = realToBigint(ord.leadingCoeff);
return n * (1n << a);
}
}
}
if (isLimit(ord)) {
return hardy(canon(ord, n), n);
}
return hardy(pred(ord), n + 1n);
};
/**
* Evaluates the slow-growing hierarchy function.
* @param ord The ordinal number alpha
* @param n The natural number in `bigint`
* @returns The result in `bigint`
*/
export const slow = (ord: Ord0, n: bigint): bigint => {
// See https://en.wikipedia.org/wiki/Slow-growing_hierarchy
if (isZero(ord)) {
return 0n;
}
if (isOne(ord)) {
return 1n;
}
const r = ord instanceof Conway ? ord.realValue : ord;
if (typeof r === "number" || typeof r === "bigint") {
return BigInt(r);
}
if (eq(ord, unit)) {
return n;
}
if (ord instanceof Conway) {
if (eq(ord, unit)) {
return n;
}
if (ord.length === 1) {
if (isOne(ord.leadingPower ?? realZero)) {
const a = realToBigint(ord.leadingCoeff);
return n + a;
}
if (isOne(ord.leadingCoeff) && !(ord.leadingPower instanceof Conway)) {
return n ** realToBigint(ord.leadingPower || 0n);
}
if (isOne(ord.leadingCoeff) && eq(ord.leadingPower ?? 0, unit)) {
return n ** n;
}
}
}
if (isLimit(ord)) {
return slow(canon(ord, n), n);
}
return slow(pred(ord), n) + 1n;
};