go-by-test/roman/roman.go

59 lines
1.1 KiB
Go
Raw Normal View History

package roman
2024-09-22 20:00:50 +00:00
import (
"errors"
"strings"
)
2024-09-22 19:12:56 +00:00
type RomanNumeral struct {
2024-09-22 19:51:40 +00:00
Value uint16
2024-09-22 19:12:56 +00:00
Symbol string
}
var allRomanNumerals = []RomanNumeral{
2024-09-22 19:24:24 +00:00
{1000, "M"},
{900, "CM"},
{500, "D"},
{400, "CD"},
{900, "CM"},
{100, "C"},
{90, "XC"},
{50, "L"},
{40, "XL"},
2024-09-22 19:12:56 +00:00
{10, "X"},
{9, "IX"},
{5, "V"},
{4, "IV"},
{1, "I"},
}
2024-09-22 20:00:50 +00:00
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
2024-09-22 19:12:56 +00:00
for _, numeral := range allRomanNumerals {
for arabic >= numeral.Value {
converted.WriteString(numeral.Symbol)
arabic -= numeral.Value
}
2024-09-22 18:57:12 +00:00
}
2024-09-22 19:02:27 +00:00
2024-09-22 20:00:50 +00:00
return converted.String(), nil
}
2024-09-22 19:28:24 +00:00
2024-09-22 20:00:50 +00:00
// XXX: This convert function doesn't check the validity of the roman numerals string
2024-09-22 19:51:40 +00:00
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
2024-09-22 19:28:24 +00:00
}