Share your thoughts in the 2024 State of Clojure Survey!

Welcome! Please see the About page for a little more info on how this works.

0 votes
in Syntax and reader by

I am working my way through a roman numerals clojure exercise.
I have
(def roman-numerals {"M" 1000 "D" 500 "C" 100 "L" 50 "X" 10 "V" 5 "I" 1})
and I'd like to convert let's say "XVI" to numbers - as a start. But

(map #(println %) (sequence "XIV"))
prints
`X
(nilI
nilV
nil)`

and

(map #(get roman-numerals %) (sequence "XIV"))
produces
(nil nil nil)

How can I get map to use the actual characters out of the sequence?

(sequence "XIV") => (\X \I \V)

2 Answers

0 votes
by
edited by
 
Best answer

Try:

(def roman-numerals {\M 1000 \D 500 \C 100 \L 50 \X 10 \V 5 \I 1})
(map roman-numerals "XVI")
;;=> (10 5 1)

If you want to keep the strings in the map:

(map #(roman-numerals (str %)) (sequence "XIV"))
by
The answer for me is that in clojure, characters are not strings, and so I needed to use character keys and not string keys.
0 votes
by

chars can be coerced to strings (anything can) with str, so one way is to operate on the string as a seq of chars, map to strings, and lookup in your map as before. The other option is to use characters as keys as mentioned.

(def roman-numerals
 {"M" 1000 "D" 500 "C" 100 "L" 50 "X" 10 "V" 5 "I" 1})
(defn unroman [numeral]
   (->> numeral
       (map (comp roman-numerals str))
       (reduce +)))

user> (unroman "XIV")
16
...