sporky_checker/lib.rs
1use rust_embed::Embed;
2
3#[derive(Embed)]
4#[folder = "data/"]
5struct Asset;
6
7/// Computes the Levenshtein distance between two strings.
8///
9/// # Arguments
10/// * `a` - The first string.
11/// * `b` - The second string.
12///
13/// # Returns
14/// * The Levenshtein distance between `a` and `b`.
15///
16/// # Example
17/// ```
18/// let distance = levenshtein_distance("sitting", "kitten");
19/// assert_eq!(distance, 3);
20/// ```
21/// lev_{a, b}(i, j) = { min {
22///
23///lev_{a, b}(i - 1, j) + 1
24///lev_{a, b}(i, j - 1) + 1
25///lev_{a, b}(i - 1, j -1) + 𝛿(a[i - 1], b[j - 1])
26///
27/// where 𝛿(a[i - 1], b[j - 1]) = 0 -> if a[i - 1] = b[j - 1]
28/// otherwise 𝛿 = 1
29pub fn levenshtein_distance(a: &str, b: &str) -> usize {
30 let m = a.len();
31 let n = b.len();
32 let a_chars: Vec<char> = a.chars().collect();
33 let b_chars: Vec<char> = b.chars().collect();
34
35 //2d matrix with 0 value and +1 offset
36 let mut matrix = vec![vec![0; n+1]; m+1];
37
38 // Base Cases
39 for i in 0..=m {
40 matrix[i][0] = i;
41 }
42
43 for j in 0..=n {
44 matrix[0][j] = j;
45 }
46
47 // Fill matrix
48 for i in 1..=m {
49 for j in 1..=n{
50
51 let cost = if a_chars[i - 1] == b_chars[j - 1] {
52 0
53 }
54 else {
55 1
56 };
57
58 matrix[i][j] = * [
59 matrix[i - 1][j] + 1, // deletion
60 matrix[i][j - 1] + 1, // insertion
61 matrix[i - 1][j - 1] + cost, // substitution
62 ]
63 .iter()
64 .min()
65 .unwrap()
66
67
68 }
69 }
70
71 //check bottom right for final score/distance
72 matrix[m][n]
73}
74
75///takes file name and parses lines
76pub fn read_word_list(file_name: &str) -> Vec<String> {
77
78 let mut list = Vec::new();
79
80 if let Some(file) = Asset::get(file_name){
81 if let Ok(lines) = std::str::from_utf8(file.data.as_ref()) {
82 for line in lines.lines() {
83 list.push(line.to_string());
84 }
85 }
86 } else {
87 eprintln!("File '{}' not found in embedded assets!", file_name);
88 }
89
90 list
91}