diff --git a/source/integer_to_roman/mod.rs b/source/integer_to_roman/mod.rs new file mode 100644 index 0000000..6ea4ea5 --- /dev/null +++ b/source/integer_to_roman/mod.rs @@ -0,0 +1,31 @@ +pub fn int_to_roman(number: i32) -> String { + let mut result = String::new(); + + for (index, digit) in number.to_string().chars().rev().enumerate() { + if digit == '0' { + continue; + } + + let digit = digit.to_digit(10).unwrap() as usize; + let magnitude = 10_usize.pow(index as u32); + + let (unit_1, unit_5, unit_10) = match magnitude { + 1 => ("I", "V", "X"), + 10 => ("X", "L", "C"), + 100 => ("C", "D", "M"), + 1000 => ("M", "", ""), + _ => ("", "", ""), + }; + + result += &match digit { + 1..=3 => unit_1.repeat(digit), + 4 => format!("{unit_5}{unit_1}"), + 5 => unit_5.to_string(), + 6..=8 => format!("{}{unit_5}", unit_1.repeat(digit - 5)), + 9 => format!("{unit_10}{unit_1}"), + _ => continue, + } + } + + result.chars().rev().collect() +} diff --git a/source/lib.rs b/source/lib.rs index 5b9f1b4..f1b2545 100644 --- a/source/lib.rs +++ b/source/lib.rs @@ -2,6 +2,7 @@ pub mod add_binary; pub mod excel_sheet_column_number; pub mod excel_sheet_column_title; pub mod implement_strstr; +pub mod integer_to_roman; pub mod isomorphic_strings; pub mod length_of_last_word; pub mod longest_common_prefix; diff --git a/tests/integer_to_roman.rs b/tests/integer_to_roman.rs new file mode 100644 index 0000000..eec999c --- /dev/null +++ b/tests/integer_to_roman.rs @@ -0,0 +1,12 @@ +use leetcode::integer_to_roman::int_to_roman; + +use test_case::test_case; + +#[test_case(0, ""; "minimum")] +#[test_case(3999, "MMMCMXCIX"; "maximum")] +#[test_case(1666, "MDCLXVI"; "every character")] +#[test_case(900, "CM"; "with subtracting")] +#[test_case(20, "XX"; "without subtracting")] +fn test_integer_to_roman(input: i32, expected: &str) { + assert_eq!(int_to_roman(input), expected); +}