91 lines
2.5 KiB
Plaintext
91 lines
2.5 KiB
Plaintext
use std::collections::HashMap;
|
|
use std::fs::File;
|
|
use std::io::{self, BufRead};
|
|
|
|
fn text_char(ch: char) -> Option<char> {
|
|
match ch {
|
|
'a' | 'b' | 'c' => Some('2'),
|
|
'd' | 'e' | 'f' => Some('3'),
|
|
'g' | 'h' | 'i' => Some('4'),
|
|
'j' | 'k' | 'l' => Some('5'),
|
|
'm' | 'n' | 'o' => Some('6'),
|
|
'p' | 'q' | 'r' | 's' => Some('7'),
|
|
't' | 'u' | 'v' => Some('8'),
|
|
'w' | 'x' | 'y' | 'z' => Some('9'),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
fn text_string(s: &str) -> Option<String> {
|
|
let mut text = String::with_capacity(s.len());
|
|
for c in s.chars() {
|
|
if let Some(t) = text_char(c) {
|
|
text.push(t);
|
|
} else {
|
|
return None;
|
|
}
|
|
}
|
|
Some(text)
|
|
}
|
|
|
|
fn print_top_words(textonyms: &Vec<(&String, &Vec<String>)>, top: usize) {
|
|
for (text, words) in textonyms.iter().take(top) {
|
|
println!("{} = {}", text, words.join(", "));
|
|
}
|
|
}
|
|
|
|
fn find_textonyms(filename: &str) -> std::io::Result<()> {
|
|
let file = File::open(filename)?;
|
|
let mut table = HashMap::new();
|
|
let mut count = 0;
|
|
|
|
for line in io::BufReader::new(file).lines() {
|
|
let mut word = line?;
|
|
word.make_ascii_lowercase();
|
|
if let Some(text) = text_string(&word) {
|
|
let words = table.entry(text).or_insert(Vec::new());
|
|
words.push(word);
|
|
count += 1;
|
|
}
|
|
}
|
|
|
|
let mut textonyms: Vec<(&String, &Vec<String>)> =
|
|
table.iter().filter(|x| x.1.len() > 1).collect();
|
|
|
|
println!(
|
|
"There are {} words in '{}' which can be represented by the digit key mapping.",
|
|
count, filename
|
|
);
|
|
println!(
|
|
"They require {} digit combinations to represent them.",
|
|
table.len()
|
|
);
|
|
println!(
|
|
"{} digit combinations represent Textonyms.",
|
|
textonyms.len()
|
|
);
|
|
|
|
let top = std::cmp::min(5, textonyms.len());
|
|
textonyms.sort_by_key(|x| (std::cmp::Reverse(x.1.len()), x.0));
|
|
println!("\nTop {} by number of words:", top);
|
|
print_top_words(&textonyms, top);
|
|
|
|
textonyms.sort_by_key(|x| (std::cmp::Reverse(x.0.len()), x.0));
|
|
println!("\nTop {} by length:", top);
|
|
print_top_words(&textonyms, top);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn main() {
|
|
let args: Vec<String> = std::env::args().collect();
|
|
if args.len() != 2 {
|
|
eprintln!("usage: {} word-list", args[0]);
|
|
std::process::exit(1);
|
|
}
|
|
match find_textonyms(&args[1]) {
|
|
Ok(()) => {}
|
|
Err(error) => eprintln!("{}: {}", args[1], error),
|
|
}
|
|
}
|