Roman Numeral Converter - The Easy Way!

So while I was solving the Roman Numeral Converter Challenge I have come upon what I consider an important realisation (for me atleast).

You can find this challenge here:
Roman Numerals

So what I realised is that I don’t really have to make a converter. I just need an object that holds the valus of roman numerals for Units, Tens, Hundreds and Thousands…

Should I desire to convert Tens-of-Thousands or more, I will simply add another property that holds the value for each Ten-Thousand.
Since each value (unit, ten, hundred…) is represented with an integer from 0-9, I can just pull the corresponding roman numeral from romanObj.

I was kind of shocked that I couldn’t find this solution… After all, it is easy to maintain and understand.

Here is my code:

function convertToRoman(num) {
  let romanArr = [];
  const romanObj = {
    0: ["","I","II","III","IV","V","VI","VII","VIII","IX"],
    1: ["","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"],
    2: ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"],
    3: ["","M","MM","MMM","MV","V","VM","VMM","VMMM","IX"]
  }
  const numArrRep = num.toString().split("").map(item => parseInt(item));
  let m = numArrRep.length - 1;
  for(let n = m; n >= 0; n--) {
    romanArr.push(romanObj[n][numArrRep[m - n]]);
  }
 return romanArr.join("");
}

convertToRoman(3999);

What would you say the drawbacks of such an approach would be?

HI @kuklin_artem !

I added spoiler tags around your code for those who have not worked on this challenge yet.
I also moved this to the javascript section since this is more of a algorithm challenge than an actual project per se.

How would your code handle convertToRoman(4000)?

it works because the challenge is for numbers up to 3999, but it’s not correct

note that MV is NOT 4000, and is not a valid roman character at all
V is not 5000, IX is not 9000

for that to be correct you need to have a dash above them (which I think is why they are not requested.

4000 is I̅V̅
5000 is V̅
6000 is V̅I̅
7000 is V̅I̅I̅
8000 is V̅I̅I̅I̅
9000 is I̅X̅

The use of the line over the top of of the numbers (vinculum) to represent numbers greater than 3999, is not part of the original Roman Numeral system. The original system was designed for the highest number to be 3999, which is the purpose of this FCC challenge. The vinculum was introduced in the Middle Ages.

I wrote functions for each place value a number might have (ones, tens, hundreds, and thousands) which used switch statements to convert each place value into its roman numeral equivalent. Then I used a series of ternary statements to evaluate the length of the number and decide which place value functions were necessary to use. Yours is much cleaner. I like it. I think I suffer from excessively long code, because I get stubborn about wanting to make something work.

Also glad to know that I shouldn’t feel bad for writing a converter that can’t handle numbers greater than 3,999.

I think I have probably seen 30 unique solutions to this challenge. The other solutions I have seen are variations on these 30.

That is a valid point, thanks for spotting it. I did leave out the vinculum. Please allow me to correct this.
Here is the correct code:

function convertToRoman(num) {
  let romanArr = [];
  const romanObj = {
    0: ["","I","II","III","IV","V","VI","VII","VIII","IX"],
    1: ["","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"],
    2: ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"],
    3: ["","M","MM","MMM","I̅V̅","V̅","V̅I̅","V̅I̅I̅","V̅I̅I̅I̅","I̅X̅"]
  }
  const numArrRep = num.toString().split("").map(item => parseInt(item));
  let m = numArrRep.length - 1;
  for(let n = m; n >= 0; n--) {
    romanArr.push(romanObj[n][numArrRep[m - n]]);
  }
 return romanArr.join("");
}

convertToRoman(5012);

Oh, will there be any problems using “non-standard” characters in code out in the real world?
I can remember having to switch the encoding in WIndosw 95-98 back when I was a kid. I assume that programmers nowadays are more aware of different encoding needs for different purposes…

I though of going the same route as you, but the potential length of the code dissuaded me. Plus I am the kind of person the alwsay manages to spell something wrong.
ANd keeping in mind how JS is case sensitive, I definitly would have spent some time searching for one typo.
:man_shrugging:

I used place values and about 20 if statements. My code is probably fifty lines.

It also bugged me a little that it only went up to 3999. I never knew that was the highest number in the Roman numeral system.

Here is my solution, very similar to yours, but i used a bi-dimensional array. BTW, it just correctly converts numbers up to 3999:

function convertToRoman(num) {
  if (num >= 4000) return;

  const roman = ` M MM MMM
 C CC CCC CD D DC DCC DCCC CM
 X XX XXX XL L LX LXX LXXX XC
 I II III IV V VI VII VIII IX`
    .split("\n")
    .map((el) => el.split(" "));

  return num
    .toString()
    .padStart(4, 0)
    .split("")
    .map((digit, index) => roman[index][digit])
    .join("");
}