Skip to content

Instantly share code, notes, and snippets.

@puredanger
Created November 28, 2012 19:15
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save puredanger/4163403 to your computer and use it in GitHub Desktop.
Save puredanger/4163403 to your computer and use it in GitHub Desktop.
Roman numeral kata in Clojure
(use 'clojure.test)
(def numerals {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"})
(defn to-roman [decimal]
(loop [[num & r :as nums] (reverse (sort (keys numerals)))
roman ""
d decimal]
(if num
(if (>= d num)
(recur nums (str roman (get numerals num)) (- d num))
(recur r roman d))
roman)))
(def digits (apply hash-map (mapcat reverse numerals)))
(defn from-roman [roman]
(loop [[c1 c2 & r] roman
d 0]
(if-let [num (and c2 (get digits (str c1 c2)))]
(recur r (+ d num))
(if-let [num (get digits (str c1))]
(recur (apply str c2 r) (+ d num))
d))))
(deftest test-round-trip
(let [nums (range 1 10000)
round-trip (map #(from-roman (to-roman %)) nums)]
(is (= nums round-trip))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment