63 lines
1.8 KiB
Text
63 lines
1.8 KiB
Text
use std::collections::BTreeSet;
|
|
use std::collections::HashSet;
|
|
use std::fs::File;
|
|
use std::io::{self, BufRead};
|
|
use std::iter::FromIterator;
|
|
|
|
fn load_dictionary(filename: &str) -> std::io::Result<BTreeSet<String>> {
|
|
let file = File::open(filename)?;
|
|
let mut dict = BTreeSet::new();
|
|
for line in io::BufReader::new(file).lines() {
|
|
let word = line?;
|
|
dict.insert(word);
|
|
}
|
|
Ok(dict)
|
|
}
|
|
|
|
fn find_teacup_words(dict: &BTreeSet<String>) {
|
|
let mut teacup_words: Vec<&String> = Vec::new();
|
|
let mut found: HashSet<&String> = HashSet::new();
|
|
for word in dict {
|
|
let len = word.len();
|
|
if len < 3 || found.contains(word) {
|
|
continue;
|
|
}
|
|
teacup_words.clear();
|
|
let mut is_teacup_word = true;
|
|
let mut chars: Vec<char> = word.chars().collect();
|
|
for _ in 1..len {
|
|
chars.rotate_left(1);
|
|
if let Some(w) = dict.get(&String::from_iter(&chars)) {
|
|
if !w.eq(word) && !teacup_words.contains(&w) {
|
|
teacup_words.push(w);
|
|
}
|
|
} else {
|
|
is_teacup_word = false;
|
|
break;
|
|
}
|
|
}
|
|
if !is_teacup_word || teacup_words.is_empty() {
|
|
continue;
|
|
}
|
|
print!("{}", word);
|
|
found.insert(word);
|
|
for w in &teacup_words {
|
|
found.insert(w);
|
|
print!(" {}", w);
|
|
}
|
|
println!();
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let args: Vec<String> = std::env::args().collect();
|
|
if args.len() != 2 {
|
|
eprintln!("Usage: teacup dictionary");
|
|
std::process::exit(1);
|
|
}
|
|
let dict = load_dictionary(&args[1]);
|
|
match dict {
|
|
Ok(dict) => find_teacup_words(&dict),
|
|
Err(error) => eprintln!("Cannot open file {}: {}", &args[1], error),
|
|
}
|
|
}
|