-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbrackets.ts
63 lines (58 loc) · 1.81 KB
/
brackets.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
type IsOpeningBracket<TBracket> = TBracket extends "(" ? "true" : "false";
type EndOfInput<TBracket> = TBracket extends "#" ? "true" : "false";
type Bracket = "(" | ")" | "#";
type State<TNumber extends AnyNumber> = {
openBrackets: TNumber;
valid: "true" | "false";
halt: "true" | "false";
};
type BracketNextState<TInput, TState extends State<any>> = {
true: {
openBrackets: TState["openBrackets"];
valid: TState["valid"];
halt: "true";
};
false: {
true: {
openBrackets: Next<TState["openBrackets"]>;
valid: "false";
halt: "false";
};
false: {
true: {
openBrackets: TState["openBrackets"];
valid: "false";
halt: "true";
};
false: {
openBrackets: Prev<TState["openBrackets"]>;
valid: IsZero<Prev<TState["openBrackets"]>>;
halt: "false";
};
}[IsZero<TState["openBrackets"]>];
}[IsOpeningBracket<TInput>];
}[EndOfInput<TInput>];
type InputType = Bracket[];
type StateType = State<AnyNumber>;
type NextState<TInput, TState extends StateType> = BracketNextState<
TInput,
TState
>;
type Run<TInput extends InputType, TState extends StateType> = {
true: TState;
false: Run<Tail<TInput>, NextState<Head<TInput>, TState>>;
}[TState["halt"]];
type InitialState = { openBrackets: _0; halt: "false"; valid: "true" };
type validBrackets<TInput extends InputType> = Run<
TInput,
InitialState
>["valid"];
function expectTrue<T extends "true">() {}
function expectFalse<T extends "false">() {}
expectTrue<validBrackets<["#"]>>();
expectTrue<validBrackets<["(", ")", "#"]>>();
expectTrue<validBrackets<["(", ")", "(", ")", "#"]>>();
expectFalse<validBrackets<["(", "#"]>>();
expectFalse<validBrackets<[")", "#"]>>();
expectFalse<validBrackets<[")", "(", "#"]>>();
expectFalse<validBrackets<["(", ")", "(", "#"]>>();