exercism/go/roman-numerals/romannumerals.go

73 lines
1.3 KiB
Go

package romannumerals
import (
"errors"
"strings"
)
// TestVersion tells exercism which tests to use
const TestVersion = 1
// ToRomanNumeral takes an int and returns it's roman numberal string value
// Or an error if it can't be done.
func ToRomanNumeral(arabic int) (string, error) {
if arabic <= 0 || arabic > 3999 {
return "", errors.New("Invalid number given")
}
var ret string
var err error
var care int
place := 1
for ; arabic > 0; arabic = (arabic - care) / 10 {
care = arabic % 10
ret = getRomanChar(care, place) + ret
place *= 10
}
if strings.Contains(ret, "?") {
err = errors.New("Invalid number given")
}
return ret, err
}
func getRomanChar(dg, pl int) string {
switch {
case dg <= 0:
return ""
case dg < 4:
return strings.Repeat(getOnesPlaceChar(pl), dg)
case dg == 4:
return getOnesPlaceChar(pl) + getFivesPlaceChar(pl)
case dg < 9:
return getFivesPlaceChar(pl) + getRomanChar(dg-5, pl)
case dg == 9:
return getOnesPlaceChar(pl) + getOnesPlaceChar(pl*10)
}
return "?"
}
func getOnesPlaceChar(pl int) string {
switch pl {
case 1:
return "I"
case 10:
return "X"
case 100:
return "C"
case 1000:
return "M"
}
return "?"
}
func getFivesPlaceChar(pl int) string {
switch pl {
case 1:
return "V"
case 10:
return "L"
case 100:
return "D"
}
return "?"
}