Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,3 +1,5 @@
|
|||
Create a function that takes a Roman numeral as its argument and returns its value as a numeric decimal integer. You don't need to validate the form of the Roman numeral.
|
||||
|
||||
Modern Roman numerals are written by expressing each decimal digit of the number to be encoded separately, starting with the leftmost digit and skipping any 0s. So 1990 is rendered "MCMXC" (1000 = M, 900 = CM, 90 = XC) and 2008 is rendered "MMVIII" (2000 = MM, 8 = VIII). The Roman numeral for 1666, "MDCLXVI", uses each letter in descending order.
|
||||
Modern Roman numerals are written by expressing each decimal digit of the number to be encoded separately, starting with the leftmost digit and skipping any 0s.
|
||||
So 1990 is rendered "MCMXC" (1000 = M, 900 = CM, 90 = XC) and 2008 is rendered "MMVIII" (2000 = MM, 8 = VIII).
|
||||
The Roman numeral for 1666, "MDCLXVI", uses each letter in descending order.
|
||||
|
|
|
|||
|
|
@ -4,3 +4,11 @@
|
|||
(partition-by identity)
|
||||
(map (partial apply +))
|
||||
(reduce #(if (< %1 %2) (+ %1 %2) (- %1 %2)))))
|
||||
|
||||
;; alternative
|
||||
(def numerals { \I 1, \V 5, \X 10, \L 50, \C 100, \D 500, \M 1000})
|
||||
(defn from-roman [s]
|
||||
(->> s .toUpperCase
|
||||
(map numerals)
|
||||
(reduce (fn [[sum lastv] curr] [(+ sum curr (if (< lastv curr) (* -2 lastv) 0)) curr]) [0,0])
|
||||
first))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import std.regex, std.algorithm;
|
||||
|
||||
immutable int[string] w2s;
|
||||
immutable uint[string] w2s;
|
||||
|
||||
pure nothrow static this() {
|
||||
w2s = ["IX": 9, "C": 100, "D": 500, "CM": 900, "I": 1,
|
||||
|
|
@ -8,7 +8,7 @@ pure nothrow static this() {
|
|||
"V": 5, "X": 10, "IV": 4];
|
||||
}
|
||||
|
||||
int toArabic(in string s) /*pure nothrow*/ {
|
||||
uint toArabic(in string s) /*pure nothrow*/ @safe /*@nogc*/ {
|
||||
return s
|
||||
.matchAll("CM|CD|XC|XL|IX|IV|[MDCLXVI]".regex)
|
||||
.map!(m => w2s[m.hit])
|
||||
|
|
|
|||
111
Task/Roman-numerals-Decode/Eiffel/roman-numerals-decode.e
Normal file
111
Task/Roman-numerals-Decode/Eiffel/roman-numerals-decode.e
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
class
|
||||
APPLICATION
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
local
|
||||
numbers: ARRAY [STRING]
|
||||
do
|
||||
numbers := <<"MCMXC", "MMVIII", "MDCLXVI",
|
||||
-- 1990 2008 1666
|
||||
"MMMCLIX", "MCMLXXVII", "MMX">>
|
||||
-- 3159 1977 2010
|
||||
across numbers as n loop
|
||||
print (n.item +
|
||||
" in Roman numerals is " +
|
||||
roman_to_decimal (n.item).out +
|
||||
" in decimal Arabic numerals.")
|
||||
print ("%N")
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Roman numerals
|
||||
|
||||
roman_to_decimal (a_str: STRING): INTEGER
|
||||
-- Decimal representation of Roman numeral `a_str'
|
||||
require
|
||||
is_roman (a_str)
|
||||
local
|
||||
l_pos: INTEGER
|
||||
cur: INTEGER -- Value of the digit read in the current iteration
|
||||
prev: INTEGER -- Value of the digit read in the previous iteration
|
||||
do
|
||||
from
|
||||
l_pos := 0
|
||||
Result := 0
|
||||
prev := 1 + max_digit_value
|
||||
until
|
||||
l_pos = a_str.count
|
||||
loop
|
||||
l_pos := l_pos + 1
|
||||
cur := roman_digit_to_decimal (a_str.at (l_pos))
|
||||
if cur <= prev then
|
||||
-- Add nonincreasing digit
|
||||
Result := Result + cur
|
||||
else
|
||||
-- Subtract previous digit from increasing digit
|
||||
Result := Result - prev + (cur - prev)
|
||||
end
|
||||
prev := cur
|
||||
end
|
||||
ensure
|
||||
Result >= 0
|
||||
end
|
||||
|
||||
is_roman (a_string: STRING): BOOLEAN
|
||||
-- Is `a_string' a valid sequence of Roman digits?
|
||||
do
|
||||
Result := across a_string as c all is_roman_digit (c.item) end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
max_digit_value: INTEGER = 1000
|
||||
|
||||
is_roman_digit (a_char: CHARACTER): BOOLEAN
|
||||
-- Is `a_char' a valid Roman digit?
|
||||
local
|
||||
l_char: CHARACTER
|
||||
do
|
||||
l_char := a_char.as_upper
|
||||
inspect l_char
|
||||
when 'I', 'V', 'X', 'L', 'C', 'D', 'M' then
|
||||
Result := True
|
||||
else
|
||||
Result := False
|
||||
end
|
||||
end
|
||||
|
||||
roman_digit_to_decimal (a_char: CHARACTER): INTEGER
|
||||
-- Decimal representation of Roman digit `a_char'
|
||||
require
|
||||
is_roman_digit (a_char)
|
||||
local
|
||||
l_char: CHARACTER
|
||||
do
|
||||
l_char := a_char.as_upper
|
||||
inspect l_char
|
||||
when 'I' then
|
||||
Result := 1
|
||||
when 'V' then
|
||||
Result := 5
|
||||
when 'X' then
|
||||
Result := 10
|
||||
when 'L' then
|
||||
Result := 50
|
||||
when 'C' then
|
||||
Result := 100
|
||||
when 'D' then
|
||||
Result := 500
|
||||
when 'M' then
|
||||
Result := 1000
|
||||
end
|
||||
ensure
|
||||
Result > 0
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -27,7 +27,7 @@ func parseRoman(s string) (r int, err error) {
|
|||
for i := len(is) - 1; i >= 0; i-- {
|
||||
// read roman digit
|
||||
c := is[i]
|
||||
k := c == 0x305 // unicode overbar combining character
|
||||
k := c == '\u0305' // unicode overbar combining character
|
||||
if k {
|
||||
if i == 0 {
|
||||
return 0, errors.New(
|
||||
|
|
@ -39,11 +39,11 @@ func parseRoman(s string) (r int, err error) {
|
|||
cv := m[c]
|
||||
if cv == 0 {
|
||||
if c == 0x0305 {
|
||||
return 0, errors.New(fmt.Sprintf(
|
||||
"Overbar combining character invalid at position %d", i))
|
||||
return 0, fmt.Errorf(
|
||||
"Overbar combining character invalid at position %d", i)
|
||||
} else {
|
||||
return 0, errors.New(fmt.Sprintf(
|
||||
"Character unrecognized as Roman digit: %c", c))
|
||||
return 0, fmt.Errorf(
|
||||
"Character unrecognized as Roman digit: %c", c)
|
||||
}
|
||||
}
|
||||
if k {
|
||||
|
|
|
|||
|
|
@ -2,23 +2,22 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var m = map[string]int{
|
||||
"I": 1,
|
||||
"V": 5,
|
||||
"X": 10,
|
||||
"L": 50,
|
||||
"C": 100,
|
||||
"D": 500,
|
||||
"M": 1000,
|
||||
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 strings.Split(roman, "") {
|
||||
for _, r := range roman {
|
||||
digit := m[r]
|
||||
if last_digit < digit {
|
||||
arabic -= 2 * last_digit
|
||||
|
|
|
|||
|
|
@ -12,9 +12,3 @@ def roman_value(roman):
|
|||
if __name__=='__main__':
|
||||
for value in "MCMXC", "MMVIII", "MDCLXVI":
|
||||
print('%s = %i' % (value, roman_value(value)))
|
||||
|
||||
""" Output:
|
||||
MCMXC = 1990
|
||||
MMVIII = 2008
|
||||
MDCLXVI = 1666
|
||||
"""
|
||||
|
|
|
|||
13
Task/Roman-numerals-Decode/R/roman-numerals-decode-1.r
Normal file
13
Task/Roman-numerals-Decode/R/roman-numerals-decode-1.r
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
romanToArabic <- function(roman) {
|
||||
romanLookup <- c(I=1L, V=5L, X=10L, L=50L, C=100L, D=500L, M=1000L)
|
||||
rSplit <- strsplit(toupper(roman), character(0)) # Split input vector into characters
|
||||
toArabic <- function(item) {
|
||||
digits <- romanLookup[item]
|
||||
if (length(digits) > 1L) {
|
||||
smaller <- (digits[-length(digits)] < digits[-1L])
|
||||
digits[smaller] <- - digits[smaller]
|
||||
}
|
||||
sum(digits)
|
||||
}
|
||||
vapply(rSplit, toArabic, integer(1))
|
||||
}
|
||||
1
Task/Roman-numerals-Decode/R/roman-numerals-decode-2.r
Normal file
1
Task/Roman-numerals-Decode/R/roman-numerals-decode-2.r
Normal file
|
|
@ -0,0 +1 @@
|
|||
romanToArabic(c("MCMXII", "LXXXVI"))
|
||||
1
Task/Roman-numerals-Decode/R/roman-numerals-decode-3.r
Normal file
1
Task/Roman-numerals-Decode/R/roman-numerals-decode-3.r
Normal file
|
|
@ -0,0 +1 @@
|
|||
as.integer(as.roman(c("MCMXII", "LXXXVI"))
|
||||
|
|
@ -9,6 +9,14 @@ def fromRoman( r:String ) : Int = {
|
|||
} }
|
||||
}
|
||||
|
||||
// Here is a another version that does a simple running sum:
|
||||
def fromRoman2(s: String) : Int = {
|
||||
val numerals = Map('I' -> 1, 'V' -> 5, 'X' -> 10, 'L' -> 50, 'C' -> 100, 'D' -> 500, 'M' -> 1000)
|
||||
|
||||
s.toUpperCase.map(numerals).foldLeft((0,0)) {
|
||||
case ((sum, last), curr) => (sum + curr + (if (last < curr) -2*last else 0), curr) }._1
|
||||
}
|
||||
}
|
||||
|
||||
// A small test
|
||||
def test( roman:String ) = println( roman + " => " + fromRoman( roman ) )
|
||||
|
|
|
|||
12
Task/Roman-numerals-Decode/Scheme/roman-numerals-decode-1.ss
Normal file
12
Task/Roman-numerals-Decode/Scheme/roman-numerals-decode-1.ss
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
(use gauche.collection) ;; for fold2
|
||||
|
||||
(define (char-val char)
|
||||
(define i (string-scan "IVXLCDM" char))
|
||||
(* (expt 10 (div i 2)) (expt 5 (mod i 2))))
|
||||
|
||||
(define (decode roman)
|
||||
(fold2
|
||||
(lambda (n sum prev-val)
|
||||
(values ((if (< n prev-val) - +) sum n) (max n prev-val)))
|
||||
0 0
|
||||
(map char-val (reverse (string->list roman)))))
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
(for-each
|
||||
(^s (format #t "~7d: ~d\n" s (decode s)))
|
||||
'("MCMLVI" "XXC" "MCMXC" "XXCIII" "IIIIX" "MIM" "LXXIIX"))
|
||||
Loading…
Add table
Add a link
Reference in a new issue