-
Notifications
You must be signed in to change notification settings - Fork 0
/
roman.go
68 lines (57 loc) · 1.32 KB
/
roman.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Package roman provides functions for
// converting arabic to roman numerals and back
package roman
import (
"strings"
)
// Largest value for roman numerals.
// "The largest number that can be represented in this notation is 3,999 (MMMCMXCIX)"
// (https://en.wikipedia.org/wiki/Roman_numerals)
const upperbound = 3999
type numeral struct {
symbol string
value int
}
var numerals = []numeral{
{"M", 1000},
{"CM", 900},
{"D", 500},
{"CD", 400},
{"C", 100},
{"XC", 90},
{"L", 50},
{"XL", 40},
{"X", 10},
{"IX", 9},
{"V", 5},
{"IV", 4},
{"I", 1},
}
// FromArabic takes an arabic numeral and converts it to
// a roman numeral. If the arabic numeral is 0 or higher than
// set upperbound (3999), it will return an empty string.
func FromArabic(arabic int) (output string) {
if arabic == 0 || arabic > upperbound {
return
}
for _, numeral := range numerals {
quotient := arabic/numeral.value
output += strings.Repeat(numeral.symbol, quotient)
arabic -= numeral.value * quotient
if arabic <= 0 {
break
}
}
return
}
// ToArabic takes a roman numeral and converts it to
// an arabic numeral (int).
func ToArabic(roman string) (output int) {
for _, numeral := range numerals {
for strings.Index(roman, numeral.symbol) == 0 {
output += numeral.value
roman = roman[len(numeral.symbol):]
}
}
return
}