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}