11use std:: collections:: HashSet ;
22
3- /// Function that returns the letters that are missing from the input slice
4- /// and are present in the English alphabet
3+ /// Represents possible errors that can occur when checking for lipograms.
4+ #[ derive( Debug , PartialEq , Eq ) ]
5+ pub enum LipogramError {
6+ /// Indicates that a non-alphabetic character was found in the input.
7+ NonAlphabeticCharacter ,
8+ /// Indicates that a missing character is not in lowercase.
9+ NonLowercaseMissingChar ,
10+ }
11+
12+ /// Computes the set of missing alphabetic characters from the input string.
513///
6- /// ## Arguments
14+ /// # Arguments
715///
8- /// * `in_str` - the slice that will be checked for missing characters
16+ /// * `in_str` - A string slice that contains the input text.
917///
18+ /// # Returns
19+ ///
20+ /// Returns a `HashSet<char>` containing the lowercase alphabetic characters that are not present in `in_str`.
1021fn compute_missing ( in_str : & str ) -> HashSet < char > {
11- let alphabet: HashSet < char > = "abcdefghijklmnopqrstuvwxyz" . chars ( ) . collect ( ) ;
22+ let alphabet: HashSet < char > = ( 'a' ..= 'z' ) . collect ( ) ;
1223
1324 let letters_used: HashSet < char > = in_str
1425 . to_lowercase ( )
@@ -19,75 +30,83 @@ fn compute_missing(in_str: &str) -> HashSet<char> {
1930 alphabet. difference ( & letters_used) . cloned ( ) . collect ( )
2031}
2132
22- /// Function that checks if the slice is a lipogram with specific missing letters.
23- /// Lipogram - sentence in which a particular letter or group of letters is avoided
24- ///
25- /// ## Arguments
33+ /// Checks if the provided string is a lipogram, meaning it is missing specific characters.
2634///
27- /// * `lipogram_str` - the slice that will be checked if is a lipogram with specific missing letters
28- /// * `missing_chars` - the characters that has to be missing
35+ /// # Arguments
2936///
30- /// ## Examples
37+ /// * `lipogram_str` - A string slice that contains the text to be checked for being a lipogram.
38+ /// * `missing_chars` - A reference to a `HashSet<char>` containing the expected missing characters.
3139///
32- /// ```
33- /// use the_algorithms_rust::string::is_lipogram;
34- /// use std::collections::HashSet;
40+ /// # Returns
3541///
36- /// assert!(
37- /// !is_lipogram("The quick brown fox jumps over the lazy dog",
38- /// &HashSet::from(['x'])
39- /// ));
40- ///
41- /// assert!(
42- /// is_lipogram("The brown cat jumped over the lazy dog with a brick",
43- /// &HashSet::from(['f', 'q', 's', 'x'])
44- /// ));
45- ///
46- /// assert!(
47- /// !is_lipogram("The quick brown fox jumped over the lazy dog",
48- /// &HashSet::from(['x'])
49- /// ));
50- /// ```
51- pub fn is_lipogram ( lipogram_str : & str , missing_chars : & HashSet < char > ) -> bool {
52- if !missing_chars. iter ( ) . all ( |& c| c. is_lowercase ( ) ) {
53- panic ! ( "missing_chars should be all lowercase." )
42+ /// Returns `Ok(true)` if the string is a lipogram that matches the provided missing characters,
43+ /// `Ok(false)` if it does not match, or a `LipogramError` if the input contains invalid characters.
44+ pub fn is_lipogram (
45+ lipogram_str : & str ,
46+ missing_chars : & HashSet < char > ,
47+ ) -> Result < bool , LipogramError > {
48+ for & c in missing_chars {
49+ if !c. is_lowercase ( ) {
50+ return Err ( LipogramError :: NonLowercaseMissingChar ) ;
51+ }
5452 }
5553
56- missing_chars == & compute_missing ( lipogram_str)
54+ for c in lipogram_str. chars ( ) {
55+ if !c. is_ascii_alphabetic ( ) && !c. is_whitespace ( ) {
56+ return Err ( LipogramError :: NonAlphabeticCharacter ) ;
57+ }
58+ }
59+
60+ let missing = compute_missing ( lipogram_str) ;
61+ Ok ( missing == * missing_chars)
5762}
5863
5964#[ cfg( test) ]
6065mod tests {
6166 use super :: * ;
67+
6268 macro_rules! test_lipogram {
63- ( $( $name: ident: $inputs: expr, ) * ) => {
64- $(
65- #[ test]
66- fn $name( ) {
67- let ( in_str, missing_chars, other_chars) = $inputs;
68- assert_ne!( missing_chars, other_chars) ;
69- assert_eq!( compute_missing( in_str) , missing_chars) ;
70- assert!( is_lipogram( in_str, & missing_chars) ) ;
71- assert!( !is_lipogram( in_str, & other_chars) ) ;
69+ ( $( $name: ident: $tc: expr, ) * ) => {
70+ $(
71+ #[ test]
72+ fn $name( ) {
73+ let ( input, missing_chars, expected) = $tc;
74+ assert_eq!( is_lipogram( input, & missing_chars) , expected) ;
75+ }
76+ ) *
7277 }
73- ) *
7478 }
75- }
7679
7780 test_lipogram ! {
78- lipogram1: ( "The quick brown fox jumps over the lazy dog" , HashSet :: from( [ ] ) , HashSet :: from( [ 'a' , 'b' ] ) ) ,
79- lipogram2: ( "Jackdaws love my big sphinx of quartz" , HashSet :: from( [ ] ) , HashSet :: from( [ 'x' ] ) ) ,
80- lipogram3: ( "abcdefghijklmnopqrstuvwxyz" , HashSet :: from( [ ] ) , HashSet :: from( [ 'x' , 'y' , 'z' ] ) ) ,
81- lipogram4: ( "Five quacking zephyrs jolt my wax bed" , HashSet :: from( [ ] ) , HashSet :: from( [ 'a' ] ) ) ,
82- lipogram5: ( "The quick brown fox jumped over the lazy dog" , HashSet :: from( [ 's' ] ) , HashSet :: from( [ ] ) ) ,
83- lipogram6: ( "abcdefghijklmnopqrstuvwxy" , HashSet :: from( [ 'z' ] ) , HashSet :: from( [ 'y' , 'z' ] ) ) ,
84- lipogram7: ( "The brown fox jumped over the lazy dog with a brick" , HashSet :: from( [ 'q' , 's' ] ) , HashSet :: from( [ 'b' ] ) ) ,
85- lipogram8: ( "ABCdefghijklmnopqrstuvwx" , HashSet :: from( [ 'y' , 'z' ] ) , HashSet :: from( [ 'a' , 'b' ] ) ) ,
86- }
87-
88- #[ test]
89- #[ should_panic]
90- fn test_is_lipogram_panics_when_missing_chars_are_upper_case ( ) {
91- is_lipogram ( "abcdefghijklmnopqrstuvwx" , & HashSet :: from ( [ 'y' , 'Z' ] ) ) ;
81+ perfect_pangram: (
82+ "The quick brown fox jumps over the lazy dog" ,
83+ HashSet :: from( [ ] ) ,
84+ Ok ( true )
85+ ) ,
86+ lipogram_single_missing: (
87+ "The quick brown fox jumped over the lazy dog" ,
88+ HashSet :: from( [ 's' ] ) ,
89+ Ok ( true )
90+ ) ,
91+ lipogram_multiple_missing: (
92+ "The brown fox jumped over the lazy dog" ,
93+ HashSet :: from( [ 'q' , 'i' , 'c' , 'k' , 's' ] ) ,
94+ Ok ( true )
95+ ) ,
96+ long_lipogram_single_missing: (
97+ "A jovial swain should not complain of any buxom fair who mocks his pain and thinks it gain to quiz his awkward air" ,
98+ HashSet :: from( [ 'e' ] ) ,
99+ Ok ( true )
100+ ) ,
101+ invalid_non_lowercase_chars: (
102+ "The quick brown fox jumped over the lazy dog" ,
103+ HashSet :: from( [ 'X' ] ) ,
104+ Err ( LipogramError :: NonLowercaseMissingChar )
105+ ) ,
106+ invalid_non_alphabetic_input: (
107+ "The quick brown fox jumps over the lazy dog 123@!" ,
108+ HashSet :: from( [ ] ) ,
109+ Err ( LipogramError :: NonAlphabeticCharacter )
110+ ) ,
92111 }
93112}
0 commit comments