Skip to content

Instantly share code, notes, and snippets.

@kimmowikman
Last active March 9, 2018 10:56
Show Gist options
  • Save kimmowikman/02993de13fab2ba7161dd7804c2d0085 to your computer and use it in GitHub Desktop.
Save kimmowikman/02993de13fab2ba7161dd7804c2d0085 to your computer and use it in GitHub Desktop.
Clojure program that converts roman numeral to decimal.
(ns roman.core
(:require [clojure.string :as str]))
(def grammar '("^M{0,4}" "^CM|^CD|^D?C{0,3}" "^XC|^XL|^L?X{0,3}" "^IX|^IV|^V?I{0,3}"))
(def values {:M 1000 :D 500 :C 100 :L 50 :X 10 :V 5 :I 1})
(defn sum-tokens [tokens]
(reduce
#(if (< %1 %2) (- %2 %1) (+ %1 %2))
(map #((keyword (str %)) values) (seq tokens))))
(defn process-rule [grule roman]
(if (not-empty grule)
(let [patt (re-pattern (first grule))
match (re-find patt roman)]
(+ (if (not-empty match)
(sum-tokens match) 0)
(process-rule (next grule) (str/replace roman patt ""))))
(if (empty? roman) 0
(throw (ex-info (str "Invalid roman numeral: " roman) {})))))
(defn -main
"Main function that converts roman numeral to decimal."
[roman]
(println "Convert " roman)
(println "Result " (try (process-rule grammar (str/upper-case roman))
(catch Exception e (.getMessage e)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment