Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
84
Task/Roman-numerals-Decode/Go/roman-numerals-decode-1.go
Normal file
84
Task/Roman-numerals-Decode/Go/roman-numerals-decode-1.go
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var m = map[rune]int{
|
||||
'I': 1,
|
||||
'V': 5,
|
||||
'X': 10,
|
||||
'L': 50,
|
||||
'C': 100,
|
||||
'D': 500,
|
||||
'M': 1000,
|
||||
}
|
||||
|
||||
func parseRoman(s string) (r int, err error) {
|
||||
if s == "" {
|
||||
return 0, errors.New("Empty string")
|
||||
}
|
||||
is := []rune(s) // easier to convert string up front
|
||||
var c0 rune // c0: roman character last read
|
||||
var cv0 int // cv0: value of cv
|
||||
|
||||
// the key to the algorithm is to process digits from right to left
|
||||
for i := len(is) - 1; i >= 0; i-- {
|
||||
// read roman digit
|
||||
c := is[i]
|
||||
k := c == '\u0305' // unicode overbar combining character
|
||||
if k {
|
||||
if i == 0 {
|
||||
return 0, errors.New(
|
||||
"Overbar combining character invalid at position 0")
|
||||
}
|
||||
i--
|
||||
c = is[i]
|
||||
}
|
||||
cv := m[c]
|
||||
if cv == 0 {
|
||||
if c == 0x0305 {
|
||||
return 0, fmt.Errorf(
|
||||
"Overbar combining character invalid at position %d", i)
|
||||
} else {
|
||||
return 0, fmt.Errorf(
|
||||
"Character unrecognized as Roman digit: %c", c)
|
||||
}
|
||||
}
|
||||
if k {
|
||||
c = -c // convention indicating overbar
|
||||
cv *= 1000
|
||||
}
|
||||
|
||||
// handle cases of new, same, subtractive, changed, in that order.
|
||||
switch {
|
||||
default: // case 4: digit change
|
||||
fallthrough
|
||||
case c0 == 0: // case 1: no previous digit
|
||||
c0 = c
|
||||
cv0 = cv
|
||||
case c == c0: // case 2: same digit
|
||||
case cv*5 == cv0 || cv*10 == cv0: // case 3: subtractive
|
||||
// handle next digit as new.
|
||||
// a subtractive digit doesn't count as a previous digit.
|
||||
c0 = 0
|
||||
r -= cv // subtract...
|
||||
continue // ...instead of adding
|
||||
}
|
||||
r += cv // add, in all cases except subtractive
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
// parse three numbers mentioned in task description
|
||||
for _, r := range []string{"MCMXC", "MMVIII", "MDCLXVI"} {
|
||||
v, err := parseRoman(r)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Println(r, "==", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
37
Task/Roman-numerals-Decode/Go/roman-numerals-decode-2.go
Normal file
37
Task/Roman-numerals-Decode/Go/roman-numerals-decode-2.go
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var m = map[rune]int{
|
||||
'I': 1,
|
||||
'V': 5,
|
||||
'X': 10,
|
||||
'L': 50,
|
||||
'C': 100,
|
||||
'D': 500,
|
||||
'M': 1000,
|
||||
}
|
||||
|
||||
// function, per task description
|
||||
func from_roman(roman string) (arabic int) {
|
||||
last_digit := 1000
|
||||
for _, r := range roman {
|
||||
digit := m[r]
|
||||
if last_digit < digit {
|
||||
arabic -= 2 * last_digit
|
||||
}
|
||||
last_digit = digit
|
||||
arabic += digit
|
||||
}
|
||||
|
||||
return arabic
|
||||
}
|
||||
|
||||
func main() {
|
||||
// parse three numbers mentioned in task description
|
||||
for _, roman_digit := range []string{"MCMXC", "MMVIII", "MDCLXVI"} {
|
||||
fmt.Printf("%-10s == %d\n", roman_digit, from_roman(roman_digit))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue