## DEV Community is a community of 552,031 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

# Roman Numeral Converter

Andy Pickle γ»Updated on γ»1 min read

My coding education journey has been a bit, disjointed to say the least. I've stop started on freeCodeCamp, CS50, other tutorials, books, and just hanging out with smart people. I made it a goal to go back and get some of the certifications I bounced around on this year, and today solved the "Roman Numeral Converter" on freeCodeCamp. I'd love to know how others solved this. Because this was just the first idea I came up with and I'm sure there are many other ways to get it done!

What are the pros and cons of your solution?

Here's mine:

## Discussion

Dian Fay

The last code test I took for an interview involved writing a calculator in Java:

``````    public Abacus() {

numerals.put("M", 1000);
numerals.put("D", 500);
numerals.put("C", 100);
numerals.put("L", 50);
numerals.put("X", 10);
numerals.put("V", 5);
numerals.put("I", 1);
}
``````
``````    /**
* Find the appropriate divisor for a value, which, in the equation
* (val - val / divisor) will resolve to the threshold at or above which
* a subtractive maneuver is necessary to convert to Roman numerals.
*/
private int getDivisor(int value) {
while (value > 10) {
value = value / 10;
}

return value;
}

public String convert(int arabic) {
StringBuilder sb = new StringBuilder();

// preserve a pointer to the last subtractable numeral
Map.Entry<String, Integer> lastEntry = null;

for (Map.Entry<String, Integer> e : numerals.entrySet()) {
if (lastEntry != null) {
if (arabic >= 4 * e.getValue()) {
// we have a valid subtraction!
sb.append(e.getKey());
sb.append(lastEntry.getKey());

arabic -= (lastEntry.getValue() - e.getValue());
} else {
// e isn't small enough for us to have a valid subtraction
// yet, keep going
continue;
}
}

// basic additive calculation: as long as the number is bigger than
// e, keep appending e
while (arabic >= e.getValue()) {
sb.append(e.getKey());

arabic -= e.getValue();
}

if (arabic >= e.getValue() - (e.getValue() / getDivisor(e.getValue()))) {
// the remaining number is close enough to e that we will need
// to perform a subtractive maneuver with reversed numerals
lastEntry = e;
}
}

return sb.toString();
}
``````

pro:

• the mapping only includes each Roman digit once
• the algorithm is aesthetically pleasing (even if Java isn't the kindest to it)

con:

• the algorithm is extremely complicated and the simpler mapping is absolutely not worth it
• although it satisfied the battery of unit tests I was given, one of the interviewers had run an extra on it that demonstrated a bug. We all had fun picking it apart, but I don't recall what the exact problem is.
Andy Pickle

Whew man, I donβt know Java at all, so this looks really complicated to me.

Dian Fay

The way it works is by subtracting until you can add based only on the one-to-one mapping in descending order. So if you're trying to convert 1990, it goes like this:

1. 1990, evaluate M (1000); 1990 > 1000 so we have an M, leaving 990 for the next iteration
2. 990 is less than 1000 so MM is wrong, but it's more than 900 (`1000 - (1000 / 10)`), so we set the `lastEntry` pointer to M and proceed
3. Now we're evaluating C (100), but `lastEntry` is set. 990 > 900 which is CM, giving us MCM so far and leaving 90. I think this is where the bug is but it works in this case :)
4. 90 > (`100 - (100 / 10)`) so `lastEntry` is now C
5. Evaluate L (50); `lastEntry` is set, but the calculation to test whether L can be subtracted fails, so we proceed
6. Evaluate X (10): the subtraction test succeeds, so 90 becomes XC and the full result is MCMXC.
Andy Pickle

Nice thatβs such a cool way of thinking about it!

ItsASine (Kayla)
``````function solution(number){
// todo: solve without defining middle values :(
var translations = {
'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
};
var value = 0;
var thisPower = 0;

Object.keys(translations).forEach(function(letter, index, array) {
thisPower = translations[letter];
value = Math.floor(number / thisPower);

number -= value * thisPower;