Skip to content

Commit 3139471

Browse files
authored
Improve Lipogram (TheAlgorithms#821)
ref: improve lipogram
1 parent d0f258a commit 3139471

File tree

1 file changed

+78
-59
lines changed

1 file changed

+78
-59
lines changed

src/string/lipogram.rs

Lines changed: 78 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
11
use 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`.
1021
fn 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)]
6065
mod 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

Comments
 (0)