-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathroman.go
112 lines (91 loc) · 1.9 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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package roman
import (
"math"
"strconv"
"strings"
)
var roman = map[string]int{
"I": 1,
"V": 5,
"X": 10,
"L": 50,
"C": 100,
"D": 500,
"M": 1000,
"N": 0,
}
// romanToInt converts roman numeral to integer.
func romanToInt(romanNumeral string) int {
if romanNumeral == "" {
return 0
}
total, lastnum, num := 0, 0, 0
for i := 0; i < len(romanNumeral); i++ {
char := romanNumeral[len(romanNumeral)-(i+1) : len(romanNumeral)-i]
num = roman[char]
if num < lastnum {
total = total - num
} else {
total = total + num
}
lastnum = num
}
return total
}
// vinculumRomanToInt converts a vinculum type of roman numberal (e.g where adding a horizontal line over a number multiplies it by 1000) to integer.
func vinculumRomanToInt(romanNumeral string) int {
blocks := strings.Split(romanNumeral, "|")
//coefficient for multiplying
q := len(blocks) - 1
total := 0
for _, block := range blocks {
num := romanToInt(block)
total += num * int(math.Pow(float64(1000), float64(q)))
q--
}
return total
}
// CompareTwoRomans compares two roman numberals.
func compareTwoRomans(roman1, roman2 string) int {
if vinculumRomanToInt(roman1) == vinculumRomanToInt(roman2) {
return 1
}
if vinculumRomanToInt(roman1) > vinculumRomanToInt(roman2) {
return 1
} else {
return -1
}
}
// integerToRoman converts int to roman numeral.
func intToRoman(number int) string {
maxRomanNumber := 3999
if number > maxRomanNumber {
return strconv.Itoa(number)
}
conversions := []struct {
value int
digit string
}{
{1000, "M"},
{900, "CM"},
{500, "D"},
{400, "CD"},
{100, "C"},
{90, "XC"},
{50, "L"},
{40, "XL"},
{10, "X"},
{9, "IX"},
{5, "V"},
{4, "IV"},
{1, "I"},
}
var roman strings.Builder
for _, conversion := range conversions {
for number >= conversion.value {
roman.WriteString(conversion.digit)
number -= conversion.value
}
}
return roman.String()
}