In this challenge, you will implement a finite state automaton (FSA) to recognize a specific pattern in a sequence of characters.
A finite state automaton is a mathematical model of computation used to design both computer programs and sequential logic circuits. It is a powerful tool for pattern matching as it consists of a finite number of states and transitions between these states based on input symbols.
Finite state automatons are widely used in text processing, lexical analysis, and many other areas where pattern recognition is essential.
You need to create an FSA that can recognize the pattern "ab*c", where:
You will implement a function recognize_pattern
that takes a string slice as input and returns a boolean indicating whether the input string matches the pattern.
match
statement.match
statement.Did You Know?
Finite state automatons have a wide range of applications outside computer science as well. For example, they are used in the design of digital circuits. In digital circuit design, an FSA can be used to create sequential circuits such as counters and communication protocol controllers. FSAs are also used in the field of linguistics to model the morphology of languages and in robotics to control the behavior of autonomous robots.
ad0x99
pub fn recognize_pattern(input: &str) -> bool { enum State { Start, A, B, } let mut state = State::Start; for c in input.chars() { state = match state { State::Start => { if c == 'a' { State::A } else { return false; } } State::A => { if c == 'b' { State::A } else if c == 'c' { State::B } else { return false; } } State::B => { return false; } }; } matches!(state, State::B)}
hinphansa
#[derive(PartialEq)]enum State { A, B, C,}pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here // 'a' can be followed by multiple b's or a single c // 'b' can be followed by multiple b's or a single c // 'c' cannot be followed by anything // other characters are invalid if input.len() == 0 { return false; } let mut state = State::A; for c in input.chars() { match state { // current state is A State::A => match c { 'a' => state = State::B, // move to state B _ => return false, }, // current state is B State::B => match c { 'b' => continue, // stay in state B 'c' => state = State::C, // move to state C _ => return false, }, State::C => return false, } } // if the last state is C, then the input is valid state == State::C}
sander-b-postnl
#[derive(PartialEq)]enum State { A, B, C}pub fn recognize_pattern(input: &str) -> bool { if input.is_empty() { return false; } let mut state = State::A; for c in input.chars() { match state { State::A => match c { 'a' => state = State::B, _ => return false, }, State::B => match c { 'b' => continue, 'c' => state = State::C, _ => return false, }, State::C => return false, } } state == State::C}
jose-bernardo
#[derive(PartialEq)]enum State { A, B, C,}pub fn recognize_pattern(input: &str) -> bool { if input.is_empty() { return false; } let mut state = State::A; for c in input.chars() { match state { State::A => match c { 'a' => state = State::B, _ => return false, }, State::B => match c { 'b' => continue, 'c' => state = State::C, _ => return false, }, State::C => return false, } } state == State::C}
kyhou
#[derive(PartialEq, Debug)]enum States { Start, Middle, End,}pub fn recognize_pattern(input: &str) -> bool { let mut state: States = States::Start; for c in input.chars() { match state { States::Start => match c { 'a' => state = States::Middle, _ => return false, }, States::Middle => match c { 'b' => continue, 'c' => state = States::End, _ => { return false; } }, States::End => return false, } } if state == States::End { return true; } false}
mk-comm
pub fn recognize_pattern(input: &str) -> bool { let mut state = 0; for ch in input.chars() { match state { 0 => { if ch == 'a' { state = 1; // Transition to State 1 } else { return false; // Invalid character } } 1 => { if ch == 'b' { state = 2; // Transition to State 2 } else if ch == 'c' { state = 3; // Transition to State 3 } else { return false; // Invalid character } } 2 => { if ch == 'b' { // Stay in State 2 } else if ch == 'c' { state = 3; // Transition to State 3 } else { return false; // Invalid character } } 3 => { // No valid transitions from final state return false; } _ => unreachable!(), } } // Accept if we are in State 3 at the end of the input state == 3}
pickx
pub fn recognize_pattern(input: &str) -> bool { let mut chars = input.chars(); let Some('a') = chars.next() else { return false }; loop { match chars.next() { Some('b') => (), Some('c') => break chars.next().is_none(), _ => break false, } }}
Mxn-ptr
#[derive(PartialEq)]enum State { Start, // Start by searching a Processing, // Check 0 or more b Complete // find c so complete}pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here let mut state = State::Start; for ch in input.chars() { state = match state { State::Start => match ch { 'a' => State::Processing, _ => return false, }, State::Processing => match ch { 'b' => State::Processing, 'c' => State::Complete, _ => return false, }, State::Complete => return false, } } state == State::Complete}
lvyuemeng
pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here // state == 0: "a" // state == 1: "..b.." // state == 2: "c" // 0 -> 1(a) // 1 -> 1(b) // 1 -> 2(c) // final in 2 let mut state = 0; for ch in input.chars() { match state { 0 => { if ch == 'a' { state = 1; } else { return false; } } 1 => { if ch == 'b' { } else if ch == 'c' { state = 2; } else { return false; } } 2 => { return false; } _ => return false, } } state == 2 }
lvyuemeng
pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here // state == 0: "a" // state == 1: "..b.." // state == 2: "c" // 0 -> 1 -> 2 // 2 -> 2 // final in 2 let mut state = 0; for ch in input.chars() { match state { 0 => { if ch == 'a' { state = 1; } else { return false; } } 1 => { if ch == 'b' { } else if ch == 'c' { state = 2; } else { return false; } } 2 => { return false; } _ => return false, } } state == 2 }
funny233-github
pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here let mut state = 0; for c in input.chars() { match state { 0 => match c { 'a' => state += 1, _ => return false, }, 1 => match c { 'b' => {} 'c' => state += 1, _ => return false, }, _ => return false, } } match state { 2 => true, _ => false }}
dantekelly
enum State { Locked, Unlocked,}struct PatternReader<'a> { state: State, pointer: usize, last_char: char, pattern: &'a str,}pub fn recognize_pattern(input: &str) -> bool { let mut pattern = PatternReader { state: State::Locked, pointer: 0, last_char: '\0', pattern: "ab*c", // Pattern with '*' as a wildcard }; if input.is_empty() { return false; } let mut input_iter = input.chars(); let mut current_char = input_iter.next(); while let Some(c) = current_char { if pattern.pointer >= pattern.pattern.len() { // Input continues after pattern is fully processed return false; } let pattern_c = pattern.pattern.chars().nth(pattern.pointer).unwrap(); if pattern_c == '*' { // '*' matches zero or more of the previous character if c == pattern.last_char { current_char = input_iter.next(); // Consume this character } else { pattern.pointer += 1; // Move to the next part of the pattern } } else if c == pattern_c { // Exact match pattern.last_char = c; pattern.pointer += 1; // Move to the next part of the pattern current_char = input_iter.next(); // Consume this character } else { if pattern.pattern.len() >= pattern.pointer + 2 { if pattern.pattern.chars().nth(pattern.pointer + 1).unwrap() == '*' && c == pattern.pattern.chars().nth(pattern.pointer + 2).unwrap() { pattern.last_char = c; pattern.pointer += 2; // Move to the next part of the pattern } else { // Mismatch return false; } } else { // Mismatch return false; } } } // Ensure the rest of the pattern can match empty input while pattern.pointer < pattern.pattern.len() { if pattern.pattern.chars().nth(pattern.pointer).unwrap() == '*' { pattern.pointer += 1; // Skip '*' } else { return false; // Remaining pattern requires more characters } } true}
Aditeya
pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here let mut chars = input.chars(); let prev = chars.next(); if !matches!(prev, Some('a')) { return false; } let mut prev = chars.next(); let mut curr = chars.next(); loop { match (prev, curr) { (Some('b'), Some('b')) | (Some('b'), Some('c')) => { prev = curr; curr = chars.next(); }, (Some('c'), None) => return true, _ => return false, } }}
Aditeya
pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here let mut chars = input.chars(); let prev = chars.next(); if !matches!(prev, Some('a')) { return false; } let mut prev = chars.next(); let mut curr = chars.next(); loop { match (prev, curr) { (Some('b'), Some('b')) | (Some('b'), Some('c')) => { prev = curr; curr = chars.next(); }, (Some('c'), None) => return true, _ => return false, } } false}
jhq223
pub fn recognize_pattern(input: &str) -> bool { if input.is_empty() { return false; } if input.chars().last() != Some('c') { return false; } if input.chars().nth(0) != Some('a') { return false; } let mut chs = input.chars().collect::<Vec<char>>(); chs.remove(chs.len() - 1); chs.remove(0); for c in chs { if c != 'b' { return false; } } return true;}
xbarnett
pub fn recognize_pattern(input: &str) -> bool { let mut v: Vec<char> = input.chars().rev().collect(); let Some('a') = v.pop() else { return false }; while v.last() == Some(&'b') { v.pop(); } v == vec!['c']}
masteryachty
#[derive(PartialEq)]enum PatternStage { FirstA, BsOrC, Complete}pub fn recognize_pattern(input: &str) -> bool { let mut pattern_stage = PatternStage::FirstA; for c in input.chars() { // Update pattern stage by checking each character pattern_stage = match pattern_stage { PatternStage::FirstA => match c { // We found the first 'a', move on to 'b' and 'c' 'a' => PatternStage::BsOrC, // Otherwise, pattern failed to match _ => return false }, PatternStage::BsOrC => match c { // If we find a 'b', stay in this stage 'b' => PatternStage::BsOrC, // If we find a 'c', we've matched the full pattern 'c' => PatternStage::Complete, // Otherwise, pattern failed to match _ => return false }, PatternStage::Complete => match c { // Once we've completed the pattern we shouldn't find any // more characters, so pattern failed to match _ => return false } } } // If we haven't returned early, the pattern matched // fully only if we reached the completed stage pattern_stage == PatternStage::Complete}
TomBaston
#[derive(PartialEq)]enum PatternStage { FirstA, BsOrC, Complete}pub fn recognize_pattern(input: &str) -> bool { let mut pattern_stage = PatternStage::FirstA; for c in input.chars() { // Update pattern stage by checking each character pattern_stage = match pattern_stage { PatternStage::FirstA => match c { // We found the first 'a', move on to 'b' and 'c' 'a' => PatternStage::BsOrC, // Otherwise, pattern failed to match _ => return false }, PatternStage::BsOrC => match c { // If we find a 'b', stay in this stage 'b' => PatternStage::BsOrC, // If we find a 'c', we've matched the full pattern 'c' => PatternStage::Complete, // Otherwise, pattern failed to match _ => return false }, PatternStage::Complete => match c { // Once we've completed the pattern we shouldn't find any // more characters, so pattern failed to match _ => return false } } } // If we haven't returned early, the pattern matched // fully only if we reached the completed stage pattern_stage == PatternStage::Complete}
qcabanes-hobby
#[derive(PartialEq)]enum Stage { One, Two, Three,}pub fn recognize_pattern(input: &str) -> bool { let mut current_stage = Stage::One; for c in input.chars() { match current_stage { Stage::One => current_stage = match c { 'a' => Stage::Two, _ => Stage::One, }, Stage::Two => current_stage = match c { 'b' => Stage::Two, 'c' => Stage::Three, _ => Stage::One, }, Stage::Three => current_stage = match c { _ => Stage::One, }, } } current_stage == Stage::Three}
SRVng
#[derive(PartialEq)]enum State { Initial, Processing, FInalized, Invalid,}impl State { pub fn validate(&self, c: char) -> State { match (self, c) { (State::Initial, 'a') => State::Processing, (State::Processing, 'b') => State::Processing, (State::Processing, 'c') => State::FInalized, _ => Self::Invalid, } }}pub fn recognize_pattern(input: &str) -> bool { let mut state = State::Initial; input.chars().for_each(|c| { state = state.validate(c); }); state.eq(&State::FInalized)}
SRVng
#[derive(Debug, PartialEq, Eq)]enum State { Initial, Processing, FInalized, Invalid,}impl State { pub fn validate(&self, c: &char) -> State { dbg!(self, c); match (self, c) { (State::Initial, 'a') => State::Processing, (State::Processing, 'b') => State::Processing, (State::Processing, 'c') => State::FInalized, _ => Self::Invalid, } }}pub fn recognize_pattern(input: &str) -> bool { let mut state = State::Initial; input.chars().for_each(|c| { state = state.validate(&c); }); state.eq(&State::FInalized)}
Burnus
#[derive(PartialEq, Eq)]enum States { Initial, AB, Final, Invalid,}impl States { fn try_next(&self, next_character: char) -> Self { match (self, next_character) { (Self::Initial, 'a') => Self::AB, (Self::AB, 'b') => Self::AB, (Self::AB, 'c') => Self::Final, _ => Self::Invalid, } }}pub fn recognize_pattern(input: &str) -> bool { let mut state = States::Initial; input.chars().for_each(|c| state = state.try_next(c)); state == States::Final}
swandyr
#[derive(PartialEq)]enum Matched { None, A, B, C}pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here let mut matched = Matched::None; for c in input.chars() { match c { 'a' => match matched { Matched::None => matched = Matched::A, Matched::A => {}, _ => return false, } 'b' => match matched { Matched::A => matched = Matched::B, Matched::B => {}, _ => return false, } 'c' => match matched { Matched::A | Matched::B => matched = Matched::C, _ => return false, } _ => return false, } } matched == Matched::C}
aleksanderkrauze
#[derive(Debug, Clone, Copy)]enum FSA { Start, CharA, CharB, CharC,}pub fn recognize_pattern(input: &str) -> bool { let mut state = FSA::Start; for letter in input.chars() { match (state, letter) { (FSA::Start, 'a') => { state = FSA::CharA; } (FSA::CharA, 'b') => { state = FSA::CharB; } (FSA::CharA, 'c') => { state = FSA::CharC; } (FSA::CharB, 'b') => { continue; } (FSA::CharB, 'c') => { state = FSA::CharC; } (_, _) => { return false; } } } return matches!(state, FSA::CharC);}
TaiPoole
pub fn recognize_pattern(input: &str) -> bool { let mut state = FSA::Pending; for letter in input.chars() { match (state, letter) { (FSA::Pending, 'a') => {state = FSA::Start}, (FSA::Start, 'b') => {state = FSA::Middle}, (FSA::Middle, 'b') => {state = FSA::Middle}, (FSA::Start, 'c') => {state = FSA::End}, (FSA::Middle, 'c') => {state = FSA::End}, _ => {state = FSA::Error} } } state == FSA::End}#[derive(PartialEq, Eq)]pub enum FSA { Pending, Start, Middle, End, Error}
hilias
pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here let mut current_state = State::Start; for c in input.chars() { match current_state { State::Start => if c == 'a' { current_state = State::A; } else { break; }, State::A => if c == 'b' { current_state = State::B; } else if c == 'c' { current_state = State::End; } else { break; }, State::B => if c == 'b' { continue; } else if c == 'c' { current_state = State::End; } else { break; }, State::End => {current_state = State::Error;}, State::Error => {break;}, } } current_state == State::End}#[derive(PartialEq)]enum State { Start, A, B, End, Error,}
vineelkovvuri
#[derive(PartialEq, Eq)]enum States { Begin, B, End,}//ab*cpub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here let mut state = States::Begin; for ch in input.chars() { match ch { 'a' if state == States::Begin => { state = States::B; } 'b' if state == States::B => { state = States::B; } 'c' if state == States::B => {state = States::End;} _ => {return false;} } } if state == States::End { return true; } false}
InsaneWaifu
pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here enum FSM { None, OneA, ManyB, OneC } let mut fsm = FSM::None; dbg!(input); for chr in input.chars() { match (fsm, chr) { (FSM::None, 'a') => {fsm = FSM::OneA}, (FSM::OneA, 'b') => {fsm = FSM::ManyB}, (FSM::OneA, 'c') => {fsm = FSM::OneC}, (FSM::ManyB, 'b') => {fsm = FSM::ManyB}, (FSM::ManyB, 'c') => {fsm = FSM::OneC}, _ => {fsm = FSM::None} } } return matches!(fsm, FSM::OneC)}
1eldiego
#[derive(PartialEq)]enum Pattern { Unknown, First, MayB, Last, Invalid,}pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here let mut state = Pattern::Unknown; for x in input.chars() { match (state, x) { (Pattern::Unknown, 'a') => state = Pattern::First, (Pattern::First, 'b') => state = Pattern::MayB, (Pattern::MayB, 'b') => state = Pattern::MayB, (Pattern::MayB, 'c') => state = Pattern::Last, (Pattern::First, 'c') => state = Pattern::Last, (_, _) => state = Pattern::Invalid, } } return state == Pattern::Last;}
Herrgrim0
pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here let mut state = FSA::Start; if input.is_empty() { return false; } else { for i in input.chars() { state = match (state, i) { (FSA::Start, 'a') => FSA::Middle, (FSA::Middle, 'b') => FSA::Middle, (FSA::Middle, 'c') => FSA::End, (_, _) => FSA::Invalid, }; if state == FSA::Invalid { return false; } } } if state != FSA::End { return false } else { return true; }}#[derive(PartialEq, Clone)]pub enum FSA { Start, Middle, End, Invalid,}
jenny07007
pub fn recognize_pattern(input: &str) -> bool { let mut state = State::Start; for i in input.chars() { state = match(state, i) { (State::Start, 'a') => State::ExpectBs, (State::ExpectBs, 'b') => State::ExpectBs, (State::ExpectBs, 'c') => State::End, _ => State::Invalid, }; if let State::Invalid = state { return false } } matches!(state, State::End)}enum State { Start, ExpectBs, End, Invalid,}
flakelolz
#[derive(Debug)]enum State { First, Second, Third(char),}pub fn recognize_pattern(input: &str) -> bool { if input.is_empty() { return false; } let mut state = State::First; for char in input.chars() { match state { State::First if char == 'a' => state = State::Second, State::Second if char == 'b' || char == 'c' => state = State::Third(char), State::Third('b') if char == 'b' => continue, State::Third('b') if char == 'c' => state = State::Third(char), _ => return false, } } matches!(state, State::Third('c'))}
Smolyan91
pub fn recognize_pattern(input: &str) -> bool { let mut state = 0; for ch in input.chars() { match state { 0 => { if ch == 'a' { state = 1; } }, 1 => { if ch == 'b' { state = 1; } else if ch == 'c' { state = 2; } }, _ => { state = 3; break; } } } state == 2}
A-ndrey
pub fn recognize_pattern(input: &str) -> bool { let mut state = State::new(input.to_string()); while let Some(st) = state { state = match st { State::End => return true, _ => st.next() } } false}enum State { A(String), B(String), C(String), End}impl State { fn new(s: String) -> Option<State> { if s.starts_with('a') { Some(State::A(s[1..].to_string())) } else { None } } fn next(&self) -> Option<State> { match self { State::A(s) | State::B(s) if s.starts_with('b') => Some(State::B(s[1..].to_string())), State::A(s) | State::B(s) if s.starts_with('c') => Some(State::C(s[1..].to_string())), State::C(s) if s.len() == 0 => Some(State::End), State::End => Some(State::End), _ => None } }}
suraboy
pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here input.starts_with('a') && input.ends_with('c') && input[1..input.len()-1] == "b".repeat(input.len() - 2)}
DarkAlessa
pub fn recognize_pattern(input: &str) -> bool { input.starts_with('a') && input.ends_with('c') && input.chars().skip(1).take(input.len() - 2).all(|c| c == 'b')}
DarkAlessa
pub fn recognize_pattern(input: &str) -> bool { let chars: Vec<char> = input.chars().collect(); matches!((chars.first(), chars.last()), (Some('a'), Some('c'))) && chars[1..chars.len() - 1].iter().all(|&c| c == 'b')}
mre
#[derive(Debug)]enum State { Init, A, B, C, Invalid,}impl State { fn next(&self, c: char) -> State { match (c, self) { ('a', State::Init) => State::A, (_, State::Init) => State::Invalid, ('a', State::A) => State::Invalid, // We can go straight from 'a' to 'c' ('c', State::A) => State::C, ('b', State::A) => State::B, (_, State::A) => State::Invalid, // Stay in State B as long as we get a 'b' ('b', State::B) => State::B, ('c', State::B) => State::C, ('c', State::C) => State::Invalid, (_, _) => State::Invalid, } }}pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here if input.is_empty() { return false; } if !input.chars().all(|c| c.is_alphabetic()) { return false; } let mut state = State::Init; for c in input.chars() { println!("Handling {c}; Current State: {state:?}"); state = state.next(c); if matches!(state, State::Invalid) { return false; } } // input is empty. Let's check if we are in the correct state matches!(state, State::C)}fn main() { assert!(!recognize_pattern("")); assert!(!recognize_pattern("123")); assert!(recognize_pattern("abc")); assert!(recognize_pattern("abbc")); assert!(!recognize_pattern("abb")); assert!(!recognize_pattern("bbc")); assert!(!recognize_pattern("a"));}
AdamEttenberger
#[derive(PartialEq, Eq)]enum State { A, BorC, Pass, Fail,}pub fn recognize_pattern(input: &str) -> bool { let mut state: State = State::A; for c in input.chars() { match state { State::A => { if c == 'a' { state = State::BorC; } else { state = State::Fail; break; } }, State::BorC => { if c == 'b' { continue; } else if c == 'c' { state = State::Pass; } else { state = State::Fail; break; } }, State::Pass => { state = State::Fail; break; }, State::Fail => unreachable!() } } state == State::Pass}
herlock77
pub fn recognize_pattern(input: &str) -> bool { // Implement your finite state automaton here // let pattern = "ab*c"; let mut chars = input.chars(); if let Some('a') = chars.next() { while let Some(next_char) = chars.next() { if next_char == 'c'{ return chars.next() == None; } else if next_char != 'b' { return false; } } } false}