Skip to content

Instantly share code, notes, and snippets.

@Vinai
Created September 22, 2017 09:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Vinai/47c4d607567bab159781fd4c3c01e9bc to your computer and use it in GitHub Desktop.
Save Vinai/47c4d607567bab159781fd4c3c01e9bc to your computer and use it in GitHub Desktop.
Roman numerals kata in Clojure early while I was learning the language.
(ns roman-numerals.core)
(def roman-numerals-map (array-map "M" 1000, "CM" 900, "D" 500, "CD" 400, "C" 100, "XC" 90,
"L" 50, "XL" 40, "X" 10, "IX" 9, "V" 5, "IV" 4, "I" 1))
(defn arabic->roman
[n]
(if (= 0 n) ""
(let [[r v] (some (fn [[r v]] (if (<= v n) [r v])) roman-numerals-map)]
(apply str (concat (repeat (int (/ n v)) r) [(arabic->roman (rem n v))])))))
(defn roman->arabic
[r]
(if (= "" r) 0
(let [numerals (reverse (keys roman-numerals-map))
n (some (fn [n]
(if (re-find (re-pattern (str n "$")) r) n)) numerals)
v (get roman-numerals-map n)]
(+ v (roman->arabic (subs r 0 (- (count r) (count n))))))))
(ns roman-numerals.core-test
(:require [clojure.test :refer :all]
[roman-numerals.core :refer :all]))
(deftest conversion-to-roman-numeral
(doseq [[n r] {0 ""
1 "I"
2 "II"
4 "IV"
5 "V"
9 "IX"
10 "X"
40 "XL"
50 "L"
90 "XC"
100 "C"
400 "CD"
500 "D"
900 "CM"
1000 "M"
1974 "MCMLXXIV"
1899 "MDCCCXCIX"}]
(testing (str n " -> " r)
(is (= r (arabic->roman n))))
(testing (str r " -> " n)
(is (= n (roman->arabic r))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment