go-by-test/roman/roman.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
}