Last active
January 4, 2021 09:38
-
-
Save miner/9ff494e7cd0c9af64d03 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; I posted an earlier version on my blog: | |
;; http://fnclojure.wordpress.com/2012/08/06/roman-numerals-in-clojure/ | |
;; This version is faster and more readable. | |
(defn range-down | |
"Returns a seq of integers from HIGH (exclusive) down to LOW (inclusive). | |
LOW defaults to 0. STEP is a positve decrement, defaults to 1. Like | |
`(reverse (range low high step))' but a bit faster." | |
([high] (range (dec high) -1 -1)) | |
([high low] (range (dec high) (dec low) -1)) | |
([high low step] | |
;; calculate nearest multiple of step + offset using mod | |
(let [h (dec high) | |
hi (- h (mod (- h low) step))] | |
(range hi (dec low) (- step))))) | |
(defn roman-lookup [c pow10] | |
(nth | |
(case c | |
\1 ["I" "X" "C" "M"] | |
\2 ["II" "XX" "CC" "MM"] | |
\3 ["III" "XXX" "CCC" "MMM"] | |
\4 ["IV" "XL" "CD"] | |
\5 ["V" "L" "D"] | |
\6 ["VI" "LX" "DC"] | |
\7 ["VII" "LXX" "DCC"] | |
\8 ["VIII" "LXXX" "DCCC"] | |
\9 ["IX" "XC" "CM"] | |
\0 ["" "" "" ""]) | |
pow10)) | |
(defn roman-numeral [n] | |
{:pre [(< 0 n 4000)]} | |
(let [digits (seq (str n))] | |
(apply str (map roman-lookup digits (range-down (count digits)))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment