-
Notifications
You must be signed in to change notification settings - Fork 2
/
math.ts
148 lines (103 loc) · 3.6 KB
/
math.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Mathematical functions implemented in the TS typesystem. #typesystem
declare function assert<T>(_: T): void
export type Array = any[]
export type Empty = []
export type ToNumber<T extends Array> = T["length"]
assert<ToNumber<[any, any, any]>>(3)
export type ToArray<
T extends number,
Acc extends Array = Empty,
> = Acc["length"] extends T ? Acc : ToArray<T, [...Acc, any]>
assert<ToArray<4>>([0, 0, 0, 0])
export type AddArrays<A extends Array, B extends Array> = [...A, ...B]
assert<AddArrays<[any, any], [any, any, any]>>([0, 0, 0, 0, 0])
export type Add<A extends number, B extends number> = ToNumber<
AddArrays<ToArray<A>, ToArray<B>>
>
assert<Add<2, 3>>(5)
export type SubtractArrays<A extends Array, B extends Array> = A extends [
...B,
...infer U,
]
? U
: Empty
assert<SubtractArrays<[any, any], [any, any, any]>>([])
assert<SubtractArrays<[any, any, any, any], [any, any, any]>>([0])
export type Subtract<A extends number, B extends number> = ToNumber<
SubtractArrays<ToArray<A>, ToArray<B>>
>
assert<Subtract<3, 2>>(1)
assert<Subtract<7, 9>>(0)
export type DecrementArray<T extends Array> = T extends [any, ...infer U]
? U
: Empty
assert<DecrementArray<[any, any, any]>>([0, 0])
export type MultiplyArrays<
A extends Array,
B extends Array,
Acc extends Array = Empty,
> = A extends Empty ? Acc : MultiplyArrays<DecrementArray<A>, B, [...Acc, ...B]>
assert<MultiplyArrays<[any, any], [any, any, any]>>([0, 0, 0, 0, 0, 0])
export type Multiply<A extends number, B extends number> = ToNumber<
MultiplyArrays<ToArray<A>, ToArray<B>>
>
assert<Multiply<56, 93>>(5208)
export type DivideArrays<
A extends Array,
B extends Array,
Acc extends Array = Empty,
> = A extends [...B, ...infer R] ? DivideArrays<R, B, [...Acc, any]> : Acc
assert<DivideArrays<[any, any, any, any], [any, any]>>([0, 0])
export type Divide<A extends number, B extends number> = ToNumber<
DivideArrays<ToArray<A>, ToArray<B>>
>
assert<Divide<89, 7>>(12)
export type ModuloArrays<A extends Array, B extends Array> = A extends [
...B,
...infer R,
]
? ModuloArrays<R, B>
: A
assert<ModuloArrays<[any, any, any, any, any], [any, any, any]>>([0, 0])
export type Modulo<A extends number, B extends number> = ToNumber<
ModuloArrays<ToArray<A>, ToArray<B>>
>
assert<Modulo<89, 7>>(5)
export type IsZeroArray<T extends Array> = T extends Empty ? true : false
assert<IsZeroArray<[any, any]>>(false)
assert<IsZeroArray<[]>>(true)
export type IsZero<T extends number> = T extends 0 ? true : false
assert<IsZero<2>>(false)
assert<IsZero<0>>(true)
export type IsEqual<A, B> = A extends B ? (B extends A ? true : false) : false
assert<IsEqual<6, 7>>(false)
assert<IsEqual<9, 9>>(true)
export type Not<T extends boolean> = T extends true ? false : true
export type IsGTEArray<A extends Array, B extends Array> = A extends [
...B,
...any[],
]
? true
: false
assert<IsGTEArray<[any, any, any], [any, any]>>(true)
assert<IsGTEArray<[any, any], [any, any]>>(true)
assert<IsGTEArray<[any], [any, any]>>(false)
export type IsGTE<A extends number, B extends number> = IsGTEArray<
ToArray<A>,
ToArray<B>
>
assert<IsGTE<7, 8>>(false)
assert<IsGTE<8, 8>>(true)
assert<IsGTE<9, 8>>(true)
export type IsLTE<A extends number, B extends number> = IsGTE<B, A>
assert<IsLTE<7, 8>>(true)
assert<IsLTE<8, 8>>(true)
assert<IsLTE<9, 8>>(false)
export type IsGT<A extends number, B extends number> = Not<IsGTE<B, A>>
assert<IsGT<7, 8>>(false)
assert<IsGT<8, 8>>(false)
assert<IsGT<9, 8>>(true)
export type IsLT<A extends number, B extends number> = Not<IsGTE<A, B>>
assert<IsLT<7, 8>>(true)
assert<IsLT<8, 8>>(false)
assert<IsLT<9, 8>>(false)