From 354a0ed1725ae5408e097164714599b6b1bb66c8 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Mon, 13 Jul 2020 08:06:08 +0200 Subject: [rust] Bob --- bob/src/lib.rs | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 bob/src/lib.rs (limited to 'bob/src') diff --git a/bob/src/lib.rs b/bob/src/lib.rs new file mode 100644 index 0000000..ae18a3d --- /dev/null +++ b/bob/src/lib.rs @@ -0,0 +1,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." + } +} -- cgit v1.2.3