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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
use std::collections::{HashMap, HashSet};
impl Solution {
pub fn solve_puzzle(word1: String, word2: String, result: String) -> HashMap<char, i32> {
let all_chars: String = format!("{}{}{}", word1, word2, result);
let unique_chars: HashSet<char> = all_chars.chars().collect();
let letters: Vec<char> = unique_chars.into_iter().collect();
let mut leading = HashSet::new();
if word1.len() > 1 {
leading.insert(word1.chars().next().unwrap());
}
if word2.len() > 1 {
leading.insert(word2.chars().next().unwrap());
}
if result.len() > 1 {
leading.insert(result.chars().next().unwrap());
}
let mut mapping = HashMap::new();
let mut used = vec![false; 10];
fn word_to_num(word: &str, mapping: &HashMap<char, i32>) -> i64 {
word.chars().fold(0, |acc, c| acc * 10 + mapping[&c] as i64)
}
fn is_valid(word1: &str, word2: &str, result: &str, mapping: &HashMap<char, i32>) -> bool {
word_to_num(word1, mapping) + word_to_num(word2, mapping) == word_to_num(result, mapping)
}
fn solve(
idx: usize,
letters: &[char],
leading: &HashSet<char>,
word1: &str,
word2: &str,
result: &str,
mapping: &mut HashMap<char, i32>,
used: &mut Vec<bool>
) -> bool {
if idx == letters.len() {
return is_valid(word1, word2, result, mapping);
}
let ch = letters[idx];
for digit in 0..=9 {
if used[digit as usize] {
continue;
}
if digit == 0 && leading.contains(&ch) {
continue;
}
mapping.insert(ch, digit);
used[digit as usize] = true;
if solve(idx + 1, letters, leading, word1, word2, result, mapping, used) {
return true;
}
used[digit as usize] = false;
mapping.remove(&ch);
}
false
}
if solve(0, &letters, &leading, &word1, &word2, &result, &mut mapping, &mut used) {
mapping
} else {
HashMap::new()
}
}
}
|