Skip to content

Instantly share code, notes, and snippets.

@attilapiros
Last active August 29, 2015 14:04
Show Gist options
  • Save attilapiros/3d59468743250089326d to your computer and use it in GitHub Desktop.
Save attilapiros/3d59468743250089326d to your computer and use it in GitHub Desktop.
(ns roman-nums.core
(:require
[clojure.test :refer [testing are]]))
(def ^:private roman-digits ["I" "V" "X" "L" "C" "D" "M"])
(def ^:private roman-partitions
(partition 3 2 roman-digits))
(defn ^:private num-to-roman-one-digit [c low middle high]
(apply str
(case c
0 (list "")
1 (list low)
2 (list low low)
3 (list low low low)
4 (list low middle)
5 (list middle)
6 (list middle low)
7 (list middle low low)
8 (list middle low low low)
9 (list low high))))
(defn num-to-roman
"Convert a number to roman"
[n]
(assert (integer? n))
(assert (not (neg? n)))
(loop [buf (), n n, partitions roman-partitions]
(if (zero? n)
(apply str buf)
(let [[[low middle high] & tail] partitions c (rem n 10)]
(recur
(conj buf
(num-to-roman-one-digit c low middle high))
(quot n 10) tail)))))
(testing
(are [i s] (= s (num-to-roman i))
1 "I", 2 "II", 3 "III", 4 "IV"
5 "V", 6 "VI", 7 "VII", 41 "XLI"
971 "CMLXXI", 871 "DCCCLXXI"
900 "CM", 91 "XCI"
9 "IX"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment