Structurally, I'd say your program is just fine.  But, it did take me
a while to convince myself that your program worked, and understand
why, so I'd say it is less clear than it could be.

When striving for clarity, it is essential to:
1. Break your program into small, easily understandable functions.
2. Include a documentation string for each function which states the
type of inputs and output, and includes a statement of purpose.
3. Include some examples (or better yet, use test cases and the new
pre/post conditions).

I reworked your example in a way that I believe to be more clear.
I'll leave it to other readers to judge:

(def roman
 (sorted-map
   1 "I",
   4 "IV",
   5 "V",
   9 "IX",
   10 "X",
   40 "XL",
   50 "L",
   90 "XC",
   100 "C",
   400 "CD",
   500 "D",
   900 "CM",
   1000 "M"
 )
)

;; Terminology used in this program:
;; A "roman number" is one of the possible keys in the above roman map.
;; A "roman numeral" is a roman string representation of a positive integer.

(defn largest-roman-number-less-than-or-equal-to
  "Takes a positive number n and returns the largest roman number less
than or equal to n"
  [n]
  (last (take-while #(<= % n) (keys roman))))

; Examples:
; (largest-roman-number-less-than-or-equal-to 432) -> 400
; (largest-roman-number-less-than-or-equal-to 57) -> 50

(defn seq-of-roman-numbers
  "Takes a positive number n and returns a sequence of roman numbers,
in descending order, that add up to n"
  [n]
  (if (zero? n) []
    (let [first-roman-number (largest-roman-number-less-than-or-equal-to n)]
      (cons first-roman-number (seq-of-roman-numbers (- n
first-roman-number))))))

; Examples:
; (seq-of-roman-numbers 432) -> '(400 10 10 10 1 1)
; (seq-of-roman-numbers 7) -> '(5 1 1)

(defn roman-numeral
  "Takes a positive number n and returns the roman numeral representation of n"
  [n]
  (apply str (map roman (seq-of-roman-numbers n))))

; Examples:
; (roman-numeral 432) -> "CDXXXII"
; (roman-numeral 7) -> "VII"


---------------------------------------

My version uses examples in comments, but if you're running Clojure
1.1 or newer, I recommend experimenting with the new test library, and
with the pre/post conditions.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to