pub fn is_valid(string: String) -> bool { // If the input string is of an odd length it cannot be valid, since every // opening character must also have a closing one. if string.len() % 2 != 0 { return false; } fn get_closing_character(character: char) -> char { match character { '[' => ']', '{' => '}', '(' => ')', _ => panic!("Invalid input character: {character}"), } } let mut stack = vec![]; for character in string.chars() { match character { // For any opening characters, add their counterpart to the stack and move // on to the next character in the string. '[' | '{' | '(' => stack.push(get_closing_character(character)), // For any other characters, get the most recent character we've seen and // if it doesn't equal the expected closing character then the string is // invalid. _ => { if character != stack.pop().unwrap_or_default() { return false; } } }; } // After the string has been looped over, if anything is left in the stack the // string is invalid. stack.len() == 0 } #[test] fn test_valid_parenthesis() { assert!(is_valid("".to_string())); assert!(is_valid("[]".to_string())); assert!(is_valid("[()]".to_string())); assert!(is_valid("[{}()]".to_string())); assert!(!is_valid("[".to_string())); assert!(!is_valid("[()".to_string())); assert!(!is_valid("((".to_string())); assert!(!is_valid("[)".to_string())); assert!(!is_valid("[(}]".to_string())); assert!(!is_valid("([{}()]}".to_string())); }