59 lines
1.1 KiB
Go
59 lines
1.1 KiB
Go
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
|
|
}
|