@@ -8,20 +8,45 @@ use phf::phf_map;
88 * URL: https://leetcode.com/problems/roman-to-integer/
99 *
1010 * Runtime: 0 ms (100%)
11- * Memory Usage: 2.32 MB (10.58 %)
11+ * Memory Usage: 2.06 MB (63.81 %)
1212 */
1313
14- const NUMERALS : [ ( char , u32 ) ; 7 ] = [
15- ( 'I' , 1 ) ,
16- ( 'V' , 5 ) ,
17- ( 'X' , 10 ) ,
18- ( 'L' , 50 ) ,
19- ( 'C' , 100 ) ,
20- ( 'D' , 500 ) ,
21- ( 'M' , 1000 ) ,
22- ] ;
23-
2414pub fn solve ( s : & str ) -> i32 {
15+ let map: HashMap < char , i32 > = HashMap :: from ( [
16+ ( 'I' , 1 ) ,
17+ ( 'V' , 5 ) ,
18+ ( 'X' , 10 ) ,
19+ ( 'L' , 50 ) ,
20+ ( 'C' , 100 ) ,
21+ ( 'D' , 500 ) ,
22+ ( 'M' , 1000 )
23+ ] ) ;
24+ let mut result = 0 ;
25+ let mut previous = '0' ;
26+ let mut subtract_previous = false ;
27+
28+ for ( i, roman) in s. chars ( ) . enumerate ( ) {
29+ let val = map. get ( & roman) . unwrap ( ) ;
30+
31+ if subtract_previous {
32+ result += val - map. get ( & previous) . unwrap ( ) ;
33+ subtract_previous = false ;
34+ continue ;
35+ }
36+
37+ if i+1 < s. len ( ) && val < map. get ( & ( s. get ( i+1 ..i+2 ) . unwrap ( ) . as_bytes ( ) [ 0 ] as char ) ) . unwrap ( ) {
38+ subtract_previous = true ;
39+ } else {
40+ result += val;
41+ }
42+
43+ previous = roman;
44+ }
45+
46+ return result;
47+ }
48+
49+ pub fn solve_rev ( s : & str ) -> i32 {
2550 let map: HashMap < char , i32 > = HashMap :: from ( [
2651 ( 'I' , 1 ) ,
2752 ( 'V' , 5 ) ,
@@ -32,29 +57,24 @@ pub fn solve(s: &str) -> i32 {
3257 ( 'M' , 1000 )
3358 ] ) ;
3459 let mut result = 0 ;
35- let mut subtract_previous = false ;
3660
37- for ( i, char) in s. chars ( ) . enumerate ( ) {
38- let val = map. get ( & char) . unwrap ( ) ;
61+ let mut previous = 0 ;
3962
40- if subtract_previous {
41- result += val - map. get ( & ( s. get ( i-1 ..i) . unwrap ( ) . as_bytes ( ) [ 0 ] as char ) ) . unwrap ( ) ;
42- subtract_previous = false ;
43- continue ;
44- }
63+ for ( i, roman) in s. chars ( ) . rev ( ) . enumerate ( ) {
64+ let val = map. get ( & roman) . unwrap ( ) ;
4565
46- if i+1 < s. len ( ) && val < map. get ( & ( s. get ( i+1 ..i+2 ) . unwrap ( ) . as_bytes ( ) [ 0 ] as char ) ) . unwrap ( ) {
47- subtract_previous = true ;
48- } else {
49- result += val;
66+ if val < & previous {
67+ result -= val
5068 }
69+ else { result += val }
5170
71+ previous = val. clone ( ) ;
5272 }
5373
54- result
74+ return result;
5575}
5676
57- pub fn solve_phf ( s : String ) -> i32 {
77+ pub fn solve_phf ( s : & str ) -> i32 {
5878 let mut result: i32 = 0 ;
5979
6080 let mut buf = [ 0 ; 1 ] ;
@@ -111,17 +131,38 @@ mod roman_to_int_tests {
111131 use super :: * ;
112132
113133 #[ test]
114- fn happy_path ( ) {
115- assert_eq ! ( solve( "LVIII" ) , 58 ) ;
134+ fn roman_i ( ) {
135+ let roman_numeral = "I" ;
136+ let ans = 1 ;
137+ assert_eq ! ( solve( roman_numeral) , ans) ;
138+ assert_eq ! ( solve_rev( roman_numeral) , ans) ;
139+ assert_eq ! ( solve_phf( roman_numeral) , ans) ;
140+ }
141+
142+ #[ test]
143+ fn roman_lviii ( ) {
144+ let roman_numeral = "LVIII" ;
145+ let ans = 58 ;
146+ assert_eq ! ( solve( roman_numeral) , ans) ;
147+ assert_eq ! ( solve_rev( roman_numeral) , ans) ;
148+ assert_eq ! ( solve_phf( roman_numeral) , ans) ;
116149 }
117150
118151 #[ test]
119- fn subtraction_before_additions ( ) {
120- assert_eq ! ( solve( "XLII" ) , 42 ) ;
152+ fn roman_xlii ( ) {
153+ let roman_numeral = "XLII" ;
154+ let ans = 42 ;
155+ assert_eq ! ( solve( roman_numeral) , ans) ;
156+ assert_eq ! ( solve_rev( roman_numeral) , ans) ;
157+ assert_eq ! ( solve_phf( roman_numeral) , ans) ;
121158 }
122159
123160 #[ test]
124- fn multiple_subtractions ( ) {
125- assert_eq ! ( solve( "MCMXCIV" ) , 1994 ) ;
161+ fn roman_mcmxciv ( ) {
162+ let roman_numeral = "MCMXCIV" ;
163+ let ans = 1994 ;
164+ assert_eq ! ( solve( roman_numeral) , ans) ;
165+ assert_eq ! ( solve_rev( roman_numeral) , ans) ;
166+ assert_eq ! ( solve_phf( roman_numeral) , ans) ;
126167 }
127168}
0 commit comments