diff options
Diffstat (limited to 'rust/anagram/src/lib.rs')
| -rw-r--r-- | rust/anagram/src/lib.rs | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/rust/anagram/src/lib.rs b/rust/anagram/src/lib.rs new file mode 100644 index 0000000..4602db0 --- /dev/null +++ b/rust/anagram/src/lib.rs | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | use std::collections::HashSet; | ||
| 2 | |||
| 3 | pub fn anagrams_for<'a>(word: &str, possible_anagrams: &[&'a str]) -> HashSet<&'a str> { | ||
| 4 | let word = word.to_lowercase(); | ||
| 5 | let word_sign = signature(&word); | ||
| 6 | possible_anagrams.iter().filter(|a| { | ||
| 7 | let a_lower = a.to_lowercase(); | ||
| 8 | word_sign == signature(&a_lower) && word != a_lower | ||
| 9 | }).cloned().collect() | ||
| 10 | } | ||
| 11 | |||
| 12 | /// Compute the signature of a word. | ||
| 13 | /// | ||
| 14 | /// In this case the signature of a word is the ordered list of its lowercased | ||
| 15 | /// UTF8 characters. | ||
| 16 | fn signature(word: &str) -> Vec<&str> { | ||
| 17 | let mut chars: Vec<&str> = vec![]; | ||
| 18 | if !word.is_empty() { | ||
| 19 | let mut start = 0; | ||
| 20 | for i in (start+1)..word.len() { | ||
| 21 | if word.is_char_boundary(i) { | ||
| 22 | chars.push(word.get(start..i).unwrap()); | ||
| 23 | start = i; | ||
| 24 | } | ||
| 25 | } | ||
| 26 | chars.push(word.get(start..).unwrap()); | ||
| 27 | chars.sort_unstable(); | ||
| 28 | } | ||
| 29 | chars | ||
| 30 | } | ||
