You want to convert decimal numbers to Roman numerals and Roman
numerals to decimal numbers.
First in the next code we can see the conversion between decimals numbers and
Roman numerals.
(define (decimal->roman num)
(let ((decimal-numbers (list 1000 900 500 400 100 90 50 40 10 9 5 4 1))
(roman-numbers (list "M" "CM" "D" "CD" "C" "XC" "L"
"XL" "X" "IX" "V" "IV" "I")))
(decimal->roman-aux num "" decimal-numbers roman-numbers)))
(define (decimal->roman-aux num s decimal-numbers roman-numbers)
(if (null? decimal-numbers)
s
(if (>= num (car decimal-numbers))
(decimal->roman-aux (- num (car decimal-numbers))
(string-append s (car roman-numbers))
decimal-numbers roman-numbers)
(decimal->roman-aux num s
(cdr decimal-numbers) (cdr roman-numbers)))))
The solution for the convertion between Roman numerals and decimal
numbers is shown in the next code.
(require (lib "13.ss" "srfi"))
(read-case-sensitive #t)
(define (roman->decimal s)
(cond
[(string= s "") 0]
[(= (string-length s) 1) (case (string->symbol s)
[(I) 1]
[(V) 5]
[(X) 10]
[(L) 50]
[(C) 100]
[(D) 500]
[(M) 1000]
[else 0])]
[else (+ (roman->dec (string-drop s 2))
(case (string->symbol (substring/shared s 0 2))
[(IV) 4]
[(IX) 9]
[(XL) 40]
[(XC) 90]
[(CD) 400]
[(CM) 900]
[else (+ (roman->dec (substring/shared s 0 1))
(roman->dec (string-drop s 1)))]))]))
In the first code we want to show a very simple solution, the main
procedure call an auxiliary procedure that makes the real work. This
procedure has 4 arguments: the number which we want to convert, the
string that contains the result, the list that contains all the
symbols that we can represent any roman numeral and the list
that contains the same elements but in a decimal representation.
Then we have 3 cases:
If the list
decimal-numbers is empty we just return the string.
If the number is greater or equal than the first element of the
decimals list we need to make a recursive call of this procedure but
with the first argument as the rest between the number and the first
element of the decimals list, and as a second argument an string that
contains that we had and the first element of the roman numeral list
and the other two arguments are the decimal and roman lists without
changes.
If the number is less than the first element of the decimal list we
just only make a recursive call with the number and the string
unchanged and the decimal and roman lists without their first
element.
In the second code we use the srfi 13 that defines many procedures to
manipulate strings, in other case it could be very difficult to
resolve.
The main idea of the algorithm is recognize between two cases:
If the first character of the string is a simple symbol
(I,V,X,L,C,D,M).
If the two first characters of the string are a double symbol (IV, IX,
XL, XC, CD, CM).
Then we just sum the decimal values of the symbol that we have
recognized.
--
EmiliaBarajas - 18 May 2004