#lang scheme

(define regla->millares
  (lambda (n)
    (if (>= n 1000)
        (begin
          (printf "Se calculan los millares: (cociente de ~a entre 1000) ~a~n~n" n (quotient n 1000))
        (string-append
         (regla->millares (quotient n 1000))
         "."
         (begin
           (printf "Se calcula el resto: (resto de ~a entre 1000) ~a~n~n" n (remainder n 1000))
           (interprete (remainder n 1000))
           )
           )
         
        )
        (interprete n)) 
    ))

(define base-de-reglas
  (list
   (list >= 900 "CM")
   (list >= 500 "D")
   (list >= 400 "CD")
   (list >= 100 "C")
   (list >= 90 "XC")
   (list >= 50 "L")
   (list >= 40 "XL")
   (list >= 10 "X")
   (list = 9 "IX")
   (list >= 5 "V")
   (list = 4 "IV")
   (list >= 1 "I") ))

(define ensaya-regla
  (lambda (natural proc valor produccion)
    (cond
     ((proc natural valor)
      (printf
       "      Regla aplicada: ~a~n~n" (list proc valor produccion))
      (values (- natural valor) produccion))
     (else (values #f #f)) ) ))

(define interprete
  (lambda (x)
    (do
        ((i 1 (add1 i))
         (natural x)
         (reglas base-de-reglas)
         (string-temp "")
         (romano ""))
      ((= natural 0) romano)
      (printf 
       "Iteración ~a. variable de control = ~a variable de producción = ~a~n~n"
       i natural romano)
      (set!-values 
       (natural string-temp) 
       (aplica-regla natural reglas))
      (set! romano 
            (string-append romano string-temp)) 
      )
    ))

(define aplica-regla
  (lambda (n base-de-reglas)
    (let-values (
                 [(num ristra) 
                  (apply 
                   ensaya-regla 
                   (cons n (first base-de-reglas)))]
                 )
      (cond
        ((null? base-de-reglas) "Fallo")
        ((not num)
         (aplica-regla n (rest base-de-reglas)))
        (else (values num ristra) ) 
        )
      )
    ))
(define natural->romano
  (lambda (natural)
    (printf "Número natural: ~a ~n~n" natural)
    (regla->millares natural)
    ))
;(natural->romano 9876)
(natural->romano 9876543)