-
-
Save luxbock/deebf89b83feaa3fa9e3 to your computer and use it in GitHub Desktop.
Problem 92
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
;; 4Clojure Question 92 | |
;; | |
;; Roman numerals are easy to recognize, but not everyone knows all the rules necessary to work with them. Write a function to parse a Roman-numeral string and return the number it represents. | |
;; | |
;; <br /><br /> | |
;; | |
;; You can assume that the input will be well-formed, in upper-case, and follow the <a href="http://en.wikipedia.org/wiki/Roman_numerals#Subtractive_principle">subtractive principle</a>. You don't need to handle any numbers greater than MMMCMXCIX (3999), the largest number representable with ordinary letters. | |
;; | |
;; Use M-x 4clojure-check-answers when you're done! | |
(= 14 (__ "XIV")) | |
(= 827 (__ "DCCCXXVII")) | |
(= 3999 (__ "MMMCMXCIX")) | |
(= 48 (__ "XLVIII")) | |
;; mine: | |
(fn [letters] | |
(let [order (zipmap "IVXLCDM" [1 5 10 50 100 500 1000]) | |
cmp (fn [a b] (compare (get order a) (get order b))) | |
magn (fn [[letter :as g]] (* (get order letter) (count g)))] | |
(loop [[f s :as xs] (partition-by identity letters) | |
acc 0] | |
(if-not s | |
(+ (magn f) acc) | |
(recur (rest xs) | |
(-> (magn f) | |
(* (cmp (first f) (first s))) | |
(+ acc))))))) | |
;; austintaylor's solution: | |
(fn [s] | |
(let [roman {"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}] | |
(reduce + (map roman | |
(re-seq #"CM|CD|XC|XL|IX|IV|[MDCLXVI]" s))))) |
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
(fn [letters] | |
(let [order (zipmap "IVXLCDM" [1 5 10 50 100 500 1000]) | |
cmp (fn [a b] (compare (get order a) (get order b))) | |
magn (fn [[letter :as g]] (* (get order letter) (count g))) | |
groups (partition-by identity letters)] | |
(+ (magn (last groups)) | |
(reduce | |
(fn [acc [[f :as fs] [s]]] | |
(-> (magn fs) | |
(* (cmp f s)) | |
(+ acc))) | |
0 (partition 2 1 groups))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment