-
Notifications
You must be signed in to change notification settings - Fork 0
/
DFA.ts
116 lines (105 loc) · 2.97 KB
/
DFA.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
type DFA = {
startState: State;
transitions: Transition[];
acceptStates: State[];
};
type Transition = {
triggeringState: State;
triggeringChar: Character;
stateToMoveTo: State;
};
type State = string;
type Input = string;
type Character = string;
function getTransition(
transitions: Transition[],
state: State,
char: Character
): Transition | undefined {
return transitions.find(
({ triggeringState, triggeringChar }) =>
triggeringState === state && triggeringChar === char
);
}
function simulateDFA(dfa: DFA, input: Input): boolean {
let state = dfa.startState;
for (const char of input) {
const transition = getTransition(dfa.transitions, state, char);
if (transition === undefined) {
console.log(`no transition at state: ${state}, char: ${char}, reject`);
return false;
} else {
state = transition.stateToMoveTo;
}
}
if (dfa.acceptStates.includes(state)) {
console.log("Input used up and now in accept state, accept");
return true;
} else {
console.log("Input used up and not in accept state, reject");
return false;
}
}
// Accepts input where 101 is a substring
const exampleDFA = {
startState: "q1",
acceptStates: ["q4"],
transitions: [
{
triggeringState: "q1",
triggeringChar: "0",
stateToMoveTo: "q2",
},
{
triggeringState: "q1",
triggeringChar: "1",
stateToMoveTo: "q1",
},
{
triggeringState: "q2",
triggeringChar: "0",
stateToMoveTo: "q3",
},
{
triggeringState: "q2",
triggeringChar: "1",
stateToMoveTo: "q1",
},
{
triggeringState: "q3",
triggeringChar: "0",
stateToMoveTo: "q3",
},
{
triggeringState: "q3",
triggeringChar: "1",
stateToMoveTo: "q4",
},
{
triggeringState: "q4",
triggeringChar: "0",
stateToMoveTo: "q4",
},
{
triggeringState: "q4",
triggeringChar: "1",
stateToMoveTo: "q4",
},
],
};
// Basic test cases
console.assert(simulateDFA(exampleDFA, "010110") === false);
console.assert(simulateDFA(exampleDFA, "0") === false);
console.assert(simulateDFA(exampleDFA, "1") === false);
console.assert(simulateDFA(exampleDFA, "11") === false);
console.assert(simulateDFA(exampleDFA, "101") === false);
console.assert(simulateDFA(exampleDFA, "100") === false);
console.assert(simulateDFA(exampleDFA, "010") === false);
console.assert(simulateDFA(exampleDFA, "") === false);
console.assert(simulateDFA(exampleDFA, "00011000") === true);
console.assert(simulateDFA(exampleDFA, "001") === true);
console.assert(simulateDFA(exampleDFA, "0001") === true);
console.assert(simulateDFA(exampleDFA, "1001") === true);
console.assert(simulateDFA(exampleDFA, "0011") === true);
console.assert(simulateDFA(exampleDFA, "0010") === true);
console.assert(simulateDFA(exampleDFA, "010101000101010") === true);