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
|
/* The solution consists of an implementation of a simple Finite State Automaton whose states and
* transition messages are represented by the `State` and `Message` enums.
*
* `process(State, Message) -> State` represents the main transition function for the FSA. This
* allows us to compute the answer with a single visit of the input string.
*
* Note: some duplicate states (`QuestLow`, `ElseLow`) are needed in order to remember whether we
* have seen a lowercase character already or not. This is probably not the minimal number of
* states required to solve the problem.
*/
enum State { Nothing, QuestLow, Quest, Yell, YellQ, ElseLow, Else }
enum Message { Whitespace, Upper, Lower, Symbol, Question }
fn to_message(c: char) -> Message {
match c as u8 {
0..=32 => Message::Whitespace, // All controll characters are considered whitespace
63 => Message::Question,
65..=90 => Message::Upper,
97..=122 => Message::Lower,
_ => Message::Symbol // Anything else (numbers incl.) is a symbol
}
}
fn process(s: State, m: Message) -> State {
match s {
State::Nothing => match m {
Message::Whitespace => s,
Message::Upper => State::Yell,
Message::Lower => State::ElseLow,
Message::Question => State::Quest,
Message::Symbol => State::Else
},
State::QuestLow => match m {
Message::Whitespace | Message::Question => s,
_ => State::ElseLow
},
State::Quest => match m {
Message::Upper => State::Yell,
Message::Lower => State::ElseLow,
Message::Symbol => State::Else,
_ => s
},
State::Yell => match m {
Message::Lower => State::ElseLow,
Message::Question => State::YellQ,
_ => s
},
State::YellQ => match m {
Message::Symbol | Message::Upper => State::Yell,
Message::Lower => State::ElseLow,
_ => s
},
State::ElseLow => match m {
Message::Question => State::QuestLow,
_ => s
},
State::Else => match m {
Message::Upper => State::Yell,
Message::Lower => State::ElseLow,
Message::Question => State::Quest,
_ => s
}
}
}
pub fn reply(message: &str) -> &str {
let state = message.chars().fold(State::Nothing, |s, c| process(s,to_message(c)));
match state {
State::Nothing => "Fine. Be that way!",
State::QuestLow | State::Quest => "Sure.",
State::Yell => "Whoa, chill out!",
State::YellQ => "Calm down, I know what I'm doing!",
_ => "Whatever."
}
}
|