From c3c71a24f9b2afba52eb42e32da767fb72047b19 Mon Sep 17 00:00:00 2001 From: dcodesdev <101001810+dcodesdev@users.noreply.github.com> Date: Wed, 5 Jun 2024 20:11:21 +0300 Subject: [PATCH] New challenge: FSA --- Cargo.lock | 4 ++ challenges/challenges.json | 12 +++++ challenges/finite-state-automaton/Cargo.toml | 6 +++ .../finite-state-automaton/description.md | 44 +++++++++++++++++++ challenges/finite-state-automaton/src/lib.rs | 29 ++++++++++++ .../finite-state-automaton/src/starter.rs | 5 +++ .../finite-state-automaton/tests/tests.rs | 23 ++++++++++ 7 files changed, 123 insertions(+) create mode 100644 challenges/finite-state-automaton/Cargo.toml create mode 100644 challenges/finite-state-automaton/description.md create mode 100644 challenges/finite-state-automaton/src/lib.rs create mode 100644 challenges/finite-state-automaton/src/starter.rs create mode 100644 challenges/finite-state-automaton/tests/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 1c77477..53a8063 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -304,6 +304,10 @@ version = "0.1.0" name = "find-the-first-palindrome" version = "0.1.0" +[[package]] +name = "finite-state-automaton" +version = "0.1.0" + [[package]] name = "fizz-buzz" version = "0.1.0" diff --git a/challenges/challenges.json b/challenges/challenges.json index 6576431..296fb79 100644 --- a/challenges/challenges.json +++ b/challenges/challenges.json @@ -231,5 +231,17 @@ "tags": ["control flow", "palindrome"], "created_at": "2024-06-05T00:00:00Z", "updated_at": "2024-06-05T00:00:00Z" + }, + { + "id": 20, + "title": "Finite State Automaton", + "slug": "finite-state-automaton", + "short_description": "Implement a finite state automaton (FSA) to recognize a specific pattern in a sequence of characters.", + "language": "RUST", + "difficulty": "HARD", + "track": "CONTROL_FLOW", + "tags": ["pattern recognition", "automata theory", "control flow"], + "created_at": "2024-06-05T00:00:00Z", + "updated_at": "2024-06-05T00:00:00Z" } ] diff --git a/challenges/finite-state-automaton/Cargo.toml b/challenges/finite-state-automaton/Cargo.toml new file mode 100644 index 0000000..00e7544 --- /dev/null +++ b/challenges/finite-state-automaton/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "finite-state-automaton" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/challenges/finite-state-automaton/description.md b/challenges/finite-state-automaton/description.md new file mode 100644 index 0000000..833894a --- /dev/null +++ b/challenges/finite-state-automaton/description.md @@ -0,0 +1,44 @@ +In this challenge, you will implement a finite state automaton (FSA) to recognize a specific pattern in a sequence of characters. Finite state automatons are widely used in text processing, lexical analysis, and many other areas where pattern recognition is essential. + +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. + +## Your Task + +You need to create an FSA that can recognize the pattern "ab\*c", where: + +- 'a' is followed by zero or more 'b's and then followed by 'c'. + +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. + +## Requirements + +- Implement the finite state automaton using Rust's enums and the `match` statement. +- The function should handle empty strings and any invalid input gracefully. +- Your FSA should consist of states and transitions implemented as Rust enums and functions. +- You must handle state transitions explicitly using the `match` statement. + +## Example + +```rust +let result = recognize_pattern("abbbc"); +assert_eq!(result, true); + +let result = recognize_pattern("ac"); +assert_eq!(result, true); + +let result = recognize_pattern("abbbd"); +assert_eq!(result, false); + +let result = recognize_pattern(""); +assert_eq!(result, false); +``` + +> 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. + +## Hints + +- Think about how you can represent states and transitions using Rust enums. +- Carefully plan the transitions between states based on the input characters. +- Make sure to handle edge cases, such as an empty input string or invalid characters. diff --git a/challenges/finite-state-automaton/src/lib.rs b/challenges/finite-state-automaton/src/lib.rs new file mode 100644 index 0000000..8976ec1 --- /dev/null +++ b/challenges/finite-state-automaton/src/lib.rs @@ -0,0 +1,29 @@ +#[derive(Debug)] +enum State { + Start, + A, + B, + C, + Invalid, +} + +pub fn recognize_pattern(input: &str) -> bool { + let mut state = State::Start; + + for ch in input.chars() { + state = match (state, ch) { + (State::Start, 'a') => State::A, + (State::A, 'b') => State::B, + (State::A, 'c') => State::C, + (State::B, 'b') => State::B, + (State::B, 'c') => State::C, + _ => State::Invalid, + }; + + if let State::Invalid = state { + return false; + } + } + + matches!(state, State::C) +} diff --git a/challenges/finite-state-automaton/src/starter.rs b/challenges/finite-state-automaton/src/starter.rs new file mode 100644 index 0000000..d33d8fd --- /dev/null +++ b/challenges/finite-state-automaton/src/starter.rs @@ -0,0 +1,5 @@ +pub fn recognize_pattern(input: &str) -> bool { + // Implement your finite state automaton here + + false +} diff --git a/challenges/finite-state-automaton/tests/tests.rs b/challenges/finite-state-automaton/tests/tests.rs new file mode 100644 index 0000000..d62184e --- /dev/null +++ b/challenges/finite-state-automaton/tests/tests.rs @@ -0,0 +1,23 @@ +#[cfg(test)] +mod tests { + use finite_state_automaton::*; + + #[test] + fn test_recognize_pattern_valid() { + assert_eq!(recognize_pattern("abbbc"), true); + assert_eq!(recognize_pattern("ac"), true); + } + + #[test] + fn test_recognize_pattern_invalid() { + assert_eq!(recognize_pattern("abbbd"), false); + assert_eq!(recognize_pattern(""), false); + } + + #[test] + fn test_recognize_pattern_edge_cases() { + assert_eq!(recognize_pattern("abbbbbc"), true); + assert_eq!(recognize_pattern("a"), false); + assert_eq!(recognize_pattern("abc"), true); + } +}