Rebol3 Code Examplex
Roman numerals/Decode
Convert a Roman numeral string into its corresponding integer value by applying the usual additive and subtractive rules.
Rebol [
title: "Rosetta code: Roman numerals/Decode"
file: %Roman_numerals-Decode.r3
url: https://rosettacode.org/wiki/Roman_numerals-Decode
]
roman-to-arabic: function [
"Converts a Roman numeral string to its Arabic integer value; returns NONE on invalid input"
roman [string!] "Roman numeral string (e.g. {XIV})"
][
arabic: 0
parse roman [
some [
[
"IIIX" (a: 7 ) | "IIX" (a: 8 ) ; 8-7 exceptions
| "XXXC" (a: 70 ) | "XXC" (a: 80 ) ; 80-70 exceptions
| "CCXM" (a: 700) | "CCM" (a: 800) ; 800-700 exceptions
; other exceptions
| "IM" (a: 999)
| "IC" (a: 99 )
| "XM" (a: 990) ; debatable
| "VC" (a: 95 ) ; debatable
; normal rules
| #"I" [ #"V" (a: 4 )| #"X" (a: 9 )| none (a: 1 )]
| #"X" [ #"L" (a: 40 )| #"C" (a: 90 )| none (a: 10 )]
| #"C" [ #"D" (a: 400)| #"M" (a: 900)| none (a: 100)]
| #"V" (a: 5)
| #"L" (a: 50)
| #"D" (a: 500)
| #"M" (a: 1000)
](
arabic: arabic + a
)
]
end | (return none)
]
arabic
]
;; tests:
foreach roman [
"XIV" ;= 14
"CMI" ;= 901
"MCMXC" ;= 1990
"MDCLXVI" ;= 1666
"MMVIII" ;= 2008
"MMXIX" ;= 2019
"MMMCMXCV" ;= 3995
; not standard:
"IIII" ;= 4
"IIXX" ;= 18
"MIC" ;= 1099
; invalid:
"XXfoo" ;= none
][
printf [-15 " -> "] [:roman roman-to-arabic :roman]
]Output:
XIV -> 14
CMI -> 901
MCMXC -> 1990
MDCLXVI -> 1666
MMVIII -> 2008
MMXIX -> 2019
MMMCMXCV -> 3995
IIII -> 4
IIXX -> 18
MIC -> 1099
XXfoo -> none