package roman import ( "errors" "strings" ) type RomanNumeral struct { Value uint16 Symbol string } var allRomanNumerals = []RomanNumeral{ {1000, "M"}, {900, "CM"}, {500, "D"}, {400, "CD"}, {900, "CM"}, {100, "C"}, {90, "XC"}, {50, "L"}, {40, "XL"}, {10, "X"}, {9, "IX"}, {5, "V"}, {4, "IV"}, {1, "I"}, } var ErrNumberOutOfRange = errors.New("numbers should not be bigger than 3999") func ConvertToRoman(arabic uint16) (string, error) { if arabic > 3999 { return "", ErrNumberOutOfRange } var converted strings.Builder for _, numeral := range allRomanNumerals { for arabic >= numeral.Value { converted.WriteString(numeral.Symbol) arabic -= numeral.Value } } return converted.String(), nil } // XXX: This convert function doesn't check the validity of the roman numerals string func ConvertToArabic(roman string) uint16 { var converted uint16 for _, numeral := range allRomanNumerals { for strings.HasPrefix(roman, numeral.Symbol) { converted += numeral.Value // roman = roman[len(numeral.Symbol):] roman = strings.TrimPrefix(roman, numeral.Symbol) } } return converted }