Roman Numbers
This roman numbers generator by Sam Cox is a nice example of recursive programming in LISP.; roman.lsp
; Sam Cox December 8, 2003
;
; LM 2003/12/12: took out type checking of n
;
;
; This function constructs a roman numeral representation from its positive
; integer argument, N. For example,
;
; (roman 1988) --> MCMLXXXVIII
;
; The Roman method of writing numbers uses two kinds of symbols: the basic
; symbols are I=1, X=10, C=100 and M=1000; the auxiliary symbols are V=5,
; L=50 and D=500. A rule prescribes that the symbol for the larger number
; always stands to the left of that for the smaller number. An exception
; is motivated by the desire to use as few symbols as possible. For
; example, the number nine can be represented as VIIII (5+4) or IX (10-1);
; the latter is preferred. Therefore, if the symbol of a smaller number
; stands at the left, the corresponding number has to be subtracted, not
; added. It is not permitted to place several basic symbols or an
; auxiliary symbol in front. For example, use CML for 950 instead of LM.
; ---
; The VNR Encyclopedia of Mathematics, W. Gellert, H. Kustner, M. Hellwich,
; and H. Kastner, eds., Van Nostrand Reinhold Company, New York, 1975.
(define (roman n)
(roman-aux "" n (first *ROMAN*) (rest *ROMAN*)))
(define (roman-aux result n pair remaining)
(roman-aux-2 result n (first pair) (second pair) remaining))
(define (roman-aux-2 result n val rep remaining)
(if
(= n 0)
result
(< n val)
(roman-aux result n (first remaining) (rest remaining))
;else
(roman-aux-2 (append result rep) (- n val) val rep remaining)))
(define (second x) (nth 1 x))
(setq *ROMAN*
'(( 1000 "M" )
( 999 "IM" )
( 990 "XM" )
( 900 "CM" )
( 500 "D" )
( 499 "ID" )
( 490 "XD" )
( 400 "CD" )
( 100 "C" )
( 99 "IC" )
( 90 "XC" )
( 50 "L" )
( 49 "IL" )
( 40 "XL" )
( 10 "X" )
( 9 "IX" )
( 5 "V" )
( 4 "IV" )
( 1 "I" )))
; end of file