1#[macro_use]
2extern crate lazy_static;
3
4use std::collections::{HashMap, HashSet};
5
6use input::clean_input;
7
8pub mod cache;
9pub mod cli;
10pub mod input;
11pub mod loading;
12pub mod solve;
13
14#[derive(Debug, Clone)]
15pub struct Word {
16 pub word: String,
17 pub candidates: HashSet<String>,
18 pub letter_map: HashMap<char, HashSet<char>>,
19}
20impl Word {
21 pub fn new(s: &str, candidates: &HashSet<String>) -> Self {
22 let mut letter_map = HashMap::new();
23
24 for word in candidates {
25 for (i, j) in s.chars().zip(word.chars()) {
26 letter_map.entry(i).or_insert(HashSet::new()).insert(j);
27 }
28 }
29
30 Word {
31 word: s.to_string(),
32 candidates: candidates.clone(),
33 letter_map,
34 }
35 }
36}
37
38pub fn normalize(s: &str) -> String {
49 let mut result = s.chars().collect::<Vec<char>>();
50 let mut replacement = b'A';
51
52 for i in 0..result.len() {
53 if result[i].is_ascii_uppercase() {
54 continue;
55 }
56
57 result = result
59 .iter()
60 .map(|&c| {
61 if c == result[i] {
62 replacement as char
63 } else {
64 c
65 }
66 })
67 .collect();
68 replacement += 1;
69 }
70
71 result.into_iter().collect()
72}
73
74pub fn load_wordlist(contents: &str) -> HashMap<String, HashSet<String>> {
76 let mut map = HashMap::new();
77
78 for word in contents.lines() {
79 let word = clean_input(word);
80 map.entry(normalize(&word))
81 .or_insert(HashSet::new())
82 .insert(word.to_string());
83 }
84
85 map
86}