[ create a new paste ] login | about

Project: programmingpraxis
Link: http://programmingpraxis.codepad.org/FxDMoASG    [ raw code | output | fork ]

programmingpraxis - Scheme, pasted on Feb 24:
(define (roman->number roman)
  (let ((romans '((#\M 1000) (#\D 500) (#\C 100) (#\L 50) (#\X 10) (#\V 5) (#\I 1))))
    (let loop ((roman (map char-upcase (string->list roman))) (prior 10000) (number 0))
      (cond ((null? roman) number)
            ((< prior (cadr (assoc (car roman) romans)))
              (loop (cdr roman)
                    10000
                    (+ number (cadr (assoc (car roman) romans)) (* prior -2))))
            (else (loop (cdr roman)
                        (cadr (assoc (car roman) romans))
                        (+ number (cadr (assoc (car roman) romans)))))))))

(define (number->roman n)
  (if (and (integer? n) (> n 0))
      (let loop ((n n)
                 (romans '((1000 #\M) (500 #\D) (100 #\C) (50 #\L) (10 #\X) (5 #\V) (1 #\I)))
                 (boundaries '(100 100 10 10 1 1 #f))
                 (s '()))
        (if (null? romans)
            (list->string (reverse s))
            (let ((roman-val (caar romans))
                  (roman-dgt (cadar romans))
                  (bdry (car boundaries)))
              (let loop2 ((q (quotient n roman-val))
                          (r (remainder n roman-val))
                          (s s))
                (if (= q 0)
                    (if (and bdry (>= r (- roman-val bdry)))
                        (loop (remainder r bdry) (cdr romans)
                              (cdr boundaries)
                              (cons roman-dgt
                                    (append
                                      (cdr (assv bdry romans))
                                      s)))
                        (loop r (cdr romans) (cdr boundaries) s))
                    (loop2 (- q 1) r (cons roman-dgt s)))))))
      (error 'number->roman "only positive integers can be romanized")))

(define (add-roman . xs)
  (number->roman (apply +
    (map roman->number xs))))

(display (add-roman "CCCLXIX" "CDXLVIII"))


Output:
1
DCCCXVII


Create a new paste based on this one


Comments: