MichaelX

Posted on

# Roman Numeral Converter FCC Solution

## JUPITER IS UPON US

Who knew ancient Romans where gonna be involved in modern day math? Well I didn't 🤷‍♂️... Some dudes in skirts making us write more code :'( perhaps Jupiter taught them more JavaScript than we know today... I wouldn't be surprised honestly.

We're continuing our FreeCodeCamp's JavaScript Algorithms and Data Structures Series with the one and only Roman Numeral Converter Algorithm. This is the second project in the series and it's a little bit tougher than the first, well not if you're Jupiter! But sorry, Dev.to only accepts humans for now, so it's just gonna be us coffee drinkers today.

Let's start with looking at the code and then I'll explain or perhaps solve it as we go.

``````function convertToRoman(num) {
return num;
}

convertToRoman(36);
``````

This is the code we are to work with, and we're to take in a number as an input and then return the value of the number in roman numerals as the output. Quite ingenious of FreeCodeCamp I'd say.

I have a feeling we're going to be creating some loops soon enough, but we'll see along the way.

The first thing I think we should do is to create a container to hold the values of the roman numerals as strings and their corresponding values in digits. For this we would use a JavaScript object.

``````function convertToRoman(num) {
const numeralsObj = {
1000: 'M',
900: 'CM',
500: 'D',
400: 'CD',
100: 'C',
90: 'XC',
50: 'L',
40: 'XL',
10: 'X',
9: 'IX',
5: 'V',
4: 'IV',
1: 'I'
}

}
``````

Here we're using an object `numeralsObj` to store the characters that make up any and every roman numeral value. Since we can use numbers as the key or property name to hold a value or property in a JavaScript object, we're using the corresponding digit values of each roman numeral as the key for each numeral.

Finally we have the first step down, but what is next?

Well the next thing I think we should do is have something to loop over in order to access each value of our `numeralsObj` object. I think using an array would do us some good in this situation so that's what we'll do next.

``````function convertToRoman(num) {
let numeralsObj = {
1000: 'M',
900: 'CM',
500: 'D',
400: 'CD',
100: 'C',
90: 'XC',
50: 'L',
40: 'XL',
10: 'X',
9: 'IX',
5: 'V',
4: 'IV',
1: 'I'
}

const numberDivision = Object.keys(numeralsObj);
// returns an array containing all the key names in the numeralsObj variable
// [1, 4, 5, 9, 10, ......, 1000]

}
``````

Here we are using a variable `numberDivision` to store an array containing each and every key of the `numeralsObj` variable, hence providing us with every digit value we need to loop over as the keys in our object are numbers and not strings. How exactly are we getting this array? Well the Object.keys() built in JavaScript method provides us with this functionality. It takes an object and returns an array consisting of the keys or names of all the properties of that object. And what do you know, we somehow managed to pick better names than Jupiter would have after all.
`ps: sorry jupiter :')`

There is a slight issue with this though. We have our array that stores the values we need, but this array is sorted by Object.keys() from lowest number to highest number. We want our array to be sorted from highest to lowest number and you'll see just why in a jiff.

We are going to use JavaScript's Array.prototype.sort() method for this. The sort method is a little bit too complex for me to fully explain in this blog, but you can always check its documentation to know more about it otherwise, this is my short explanation of what it does. It takes an array and sorts it depending on the callback function passed into it. Otherwise if there is no callback, it performs a default sorting operation.

Here is the code with the sorting method applied:

``````const numberDivision = Object.keys(numeralsObj).sort((a, b) => b - a);
// sorts the numbers in the array from biggest number to smallest number [1000, 900, 500, 400, ........., 1]
``````

In summary, the callback function we are passing into the sort method tells it to sort the numbers in the array from biggest to smallest.

Next we are going ahead to implement our loop.
`we're a step ahead of you Jupiter :)... prolly cos u wearing a skirt lol...`

``````function convertToRoman(num) {
const numeralsObj = {
1000: 'M',
900: 'CM',
500: 'D',
400: 'CD',
100: 'C',
90: 'XC',
50: 'L',
40: 'XL',
10: 'X',
9: 'IX',
5: 'V',
4: 'IV',
1: 'I'
}

const numberDivision = Object.keys(numeralsObj).sort((a, b) => b - a);
// returns an array containing all the key names (numbers) in the numeralsObj variable and sorts the numbers from biggest number to smallest number [1000, 900, 500, 400, ........., 1]

let value = num
let result = ""

// loops over each number in the numberDivision variable
numberDivision.forEach(division => {

})

return result
}
``````

Here we are using an Array.prototype.forEach() to loop over the `numberDivision` array and check all its values to see which of their corresponding roman numerals will be added to our result string, and just when we should do so.

I also created two variables, `value` and `result`.
We are using `value` to store the input number so we do not have to modify the original input `we abide in the laws of functional programming`. We are also creating `result` in order to store our final roman numeral string.
Notice this variables are created with `let` and not `const` because we are going to change them later in the code.

We are also returning what would be our final result at the end of the function.

`hey Jupiter, it's whooping time, we wrote this code like a piece of pie`
Hey, what do you think all programmers become rappers. It'd be pretty cool actually, we'd be prograppers. If you don't think that's cool, wait until you realize that rn you're just a pro grandma. How cool is that? :(...
`shhhh: Jupiter can't be aware of this.`

Now let's complete the code with the final puzzle piece.

``````function convertToRoman(num) {
const numeralsObj = {
1000: 'M',
900: 'CM',
500: 'D',
400: 'CD',
100: 'C',
90: 'XC',
50: 'L',
40: 'XL',
10: 'X',
9: 'IX',
5: 'V',
4: 'IV',
1: 'I'
}

const numberDivision = Object.keys(numeralsObj).sort((a, b) => b - a);
// returns an array containing all the key names (numbers) in the numeralsObj variable and sorts the numbers from biggest number to smallest number [1000, 900, 500, 400, ........., 1]

let value = num
let result = ""

// loops over each number in the numberDivision variable
numberDivision.forEach(division => {
// checks the current number and performs code if value is greater than or equal to the number
while (value >= division) {
result += numeralsObj[division] // adds the numeral to our result string
value -= division // subtracts the corresponding digit from the value variable
}
})

return result // final roman numeral
}

convertToRoman(36) // returns "XXXVI"

``````

We have created a while loop which checks the numbers in the `numberDivision` array and adds their corresponding roman numerals to `result` if `value` is greater than or equal to the current number being checked. After adding the roman numeral to `result`, it then subtracts the corresponding digit from `value` and checks again until `value` is zero.

This is how it works:

Say we have an input of `5381`, we store this input in `value`, then the while loop starts checking `numberDivision` from its first item which is `1000`. It checks if `5381` is greater than or equal to `1000` and it is, so it runs the code block which adds the value of `1000` in `numeralsObj` which is `"M"` to `result`, then subtracts the current number being checked in `numberDivision` from `value` i.e it subtracts `1000` from `value` and `value` is now left with only `4381`. It then runs the while loop again and again until `value` is not greater than or equal to i.e `value` is less than `1000`, which means `value` is now only `381` and `result` is now `"MMMMM"` because the while loop condition returned `true` five times for `1000`. It then checks for `900`, `500` and `400` which all returns `false`.

`100` is now checked which returns `true` three times until `value` is `81` and `result` is `"MMMMMCCC"`. `90` is now checked, and returns `false`, then `50` is checked and returns `true`, so the code runs. `40` is checked which is also `false`, as `value` is now `31` and result is `"MMMMMCCCL"`.
`10` returns `true` three times when checked and leaves `value` with just `1` and result with `"MMMMMCCCLXXX"`, then `9`, `5` and `4` are checked, they all return `false` until the code checks `1` which returns `true` so `value` is subtracted by `1`, and is now zero and `result` is `"MMMMMCCCLXXXI"`.

Since value is zero and all the numbers in `numberDivision` have been checked, the loop stops and the JavaScript proceeds to the next step which is returning `result` and voila, we have our Roman Numeral.

This is why we needed our array to be in highest to lowest order because when checking, we start with a high value and not a low one or else all our results would be a series of `I's` to as much as input as we put in. But with the highest to lowest order our array uses, it checks the big numbers first and runs code for them if needed before going to the smaller numbers as `value` decreases.

These are the steps we followed:

• First we created an object to store the roman numerals an their corresponding digits.
• Next, we created a variable to store an array of all the digits we need to loop over.
• Next we sorted this digits array from highest to lowest
• Next we created two variables to store our input value and final result.
• Next we created a forEach loop to loop over every element in our digits array.
• Next we used a while loop to check if value is greater than or equal to the current digit in the digits array.
• Next we passed in the required numeral to result and decreased value.
• Lastly, we return our final result which holds the our roman numeral.

Here is the final code:

``````function convertToRoman(num) {
const numeralsObj = {
1000: 'M',
900: 'CM',
500: 'D',
400: 'CD',
100: 'C',
90: 'XC',
50: 'L',
40: 'XL',
10: 'X',
9: 'IX',
5: 'V',
4: 'IV',
1: 'I'
}

const numberDivision = Object.keys(numeralsObj).sort((a, b) => b - a);

let value = num
let result = ""

numberDivision.forEach(division => {
while (value >= division) {
result += numeralsObj[division]
value -= division
}
})

return result
}

convertToRoman(36)
``````

There are far more faster and lesser code demanding ways of doing this but I find this solution easier to understand, especially for newbies in development.

And just so you know Jupiter, your skirts don't scare us, we have the power of StackOverflow. And you know what they say,

he who steals code, eats gold

and feels bold btw, and probably doesn't feel cold or smthn lyk dat.

`Ok enough with the rhymes I've told, they're just too much I don't think anyone is sold, I might just need to hit the road.`

Thanks for reading and make sure you do not subscribe or like the post so I'll get notified to post more. And just like before, see you in the next post.