73 lines
1.3 KiB
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 "?"
|
|
}
|