aboutsummaryrefslogtreecommitdiff
path: root/rust/anagram/src/lib.rs
blob: 4602db02ce0a1562b79b34c2a6e203906ef909f1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
use std::collections::HashSet;

pub fn anagrams_for<'a>(word: &str, possible_anagrams: &[&'a str]) -> HashSet<&'a str> {
    let word = word.to_lowercase();
    let word_sign = signature(&word);
    possible_anagrams.iter().filter(|a| {
        let a_lower = a.to_lowercase();
        word_sign == signature(&a_lower) && word != a_lower
    }).cloned().collect()
}

/// Compute the signature of a word.
///
/// In this case the signature of a word is the ordered list of its lowercased
/// UTF8 characters.
fn signature(word: &str) -> Vec<&str> {
    let mut chars: Vec<&str> = vec![];
    if !word.is_empty() {
        let mut start = 0;
        for i in (start+1)..word.len() {
            if word.is_char_boundary(i) {
                chars.push(word.get(start..i).unwrap());
                start = i;
            }
        }
        chars.push(word.get(start..).unwrap());
        chars.sort_unstable();
    }
    chars
}