n_roman/
lib.rs

1use wasm_bindgen::prelude::*;
2
3#[wasm_bindgen]
4pub fn to_roman(num: i32) -> String {
5    if num <= 0 {
6        return String::new();
7    }
8
9    let mut result: String = String::new();
10    let mut n: i32 = num;
11
12    for (value, symbol) in [
13        (1000, "M"),
14        (900, "CM"),
15        (500, "D"),
16        (400, "CD"),
17        (100, "C"),
18        (90, "XC"),
19        (50, "L"),
20        (40, "XL"),
21        (10, "X"),
22        (9, "IX"),
23        (5, "V"),
24        (4, "IV"),
25        (1, "I"),
26    ] {
27        while n >= value {
28            result.push_str(symbol);
29            n -= value;
30        }
31    }
32
33    result
34}
35
36#[wasm_bindgen]
37pub fn from_roman(roman: &str) -> i32 {
38    let roman_chars: Vec<char> = roman.chars().collect();
39    let mut num: i32 = 0;
40
41    for i in 0..roman_chars.len() {
42        let cur_val = match roman_chars[i] {
43            'I' => 1,
44            'V' => 5,
45            'X' => 10,
46            'L' => 50,
47            'C' => 100,
48            'D' => 500,
49            'M' => 1000,
50            _ => 0, // invalid character
51        };
52
53        let next_val = if i + 1 < roman_chars.len() {
54            match roman_chars[i + 1] {
55                'I' => 1,
56                'V' => 5,
57                'X' => 10,
58                'L' => 50,
59                'C' => 100,
60                'D' => 500,
61                'M' => 1000,
62                _ => 0, // invalid character
63            }
64        } else {
65            0
66        };
67
68        if cur_val < next_val {
69            num -= cur_val;
70        } else {
71            num += cur_val;
72        }
73    }
74
75    num
76}
77
78#[cfg(test)]
79mod tests {
80    use wasm_bindgen_test::wasm_bindgen_test;
81    use super::{from_roman, to_roman};
82    
83    wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
84    
85    #[test]
86    #[wasm_bindgen_test]
87    fn three_thousand_nine_hundred_ninety_nine() {
88        assert_eq!(to_roman(3999), "MMMCMXCIX");
89        assert_eq!(from_roman("MMMCMXCIX"), 3999);
90    }
91
92    #[test]
93    #[wasm_bindgen_test]
94    fn one_thousand() {
95        assert_eq!(to_roman(1000), "M");
96        assert_eq!(from_roman("M"), 1000);
97    }
98
99    #[test]
100    #[wasm_bindgen_test]
101    fn nine_hundred() {
102        assert_eq!(to_roman(900), "CM");
103        assert_eq!(from_roman("CM"), 900);
104    }
105
106    #[test]
107    #[wasm_bindgen_test]
108    fn five_hundred() {
109        assert_eq!(to_roman(500), "D");
110        assert_eq!(from_roman("D"), 500);
111    }
112
113    #[test]
114    #[wasm_bindgen_test]
115    fn four_hundred() {
116        assert_eq!(to_roman(400), "CD");
117        assert_eq!(from_roman("CD"), 400);
118    }
119
120    #[test]
121    #[wasm_bindgen_test]
122    fn one_hundred() {
123        assert_eq!(to_roman(100), "C");
124        assert_eq!(from_roman("C"), 100);
125    }
126
127    #[test]
128    #[wasm_bindgen_test]
129    fn ninety() {
130        assert_eq!(to_roman(90), "XC");
131        assert_eq!(from_roman("XC"), 90);
132    }
133
134    #[test]
135    #[wasm_bindgen_test]
136    fn fifty() {
137        assert_eq!(to_roman(50), "L");
138        assert_eq!(from_roman("L"), 50);
139    }
140
141    #[test]
142    #[wasm_bindgen_test]
143    fn forty() {
144        assert_eq!(to_roman(40), "XL");
145        assert_eq!(from_roman("XL"), 40);
146    }
147
148    #[test]
149    #[wasm_bindgen_test]
150    fn ten() {
151        assert_eq!(to_roman(10), "X");
152        assert_eq!(from_roman("X"), 10);
153    }
154
155    #[test]
156    #[wasm_bindgen_test]
157    fn nine() {
158        assert_eq!(to_roman(9), "IX");
159        assert_eq!(from_roman("IX"), 9);
160    }
161
162    #[test]
163    #[wasm_bindgen_test]
164    fn five() {
165        assert_eq!(to_roman(5), "V");
166        assert_eq!(from_roman("V"), 5);
167    }
168
169    #[test]
170    #[wasm_bindgen_test]
171    fn four() {
172        assert_eq!(to_roman(4), "IV");
173        assert_eq!(from_roman("IV"), 4);
174    }
175
176    #[test]
177    #[wasm_bindgen_test]
178    fn one() {
179        assert_eq!(to_roman(1), "I");
180        assert_eq!(from_roman("I"), 1);
181    }
182}