-
-
Save colingourlay/2417038 to your computer and use it in GitHub Desktop.
(function () { | |
function romanify(value) { | |
var numbers, numerals, result, i, len; | |
numbers = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 ]; | |
numerals = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"]; | |
result = ""; | |
for (i = 0, len = numbers.length; i < len; i++) { | |
while (value >= numbers[i]) { | |
value -= numbers[i]; | |
result += numerals[i]; | |
} | |
} | |
return result; | |
} | |
function shouldEqual(a, b) { | |
var result; | |
result = a == b; | |
if (!result) { | |
console.log(["shouldEqual: expected ", b, " but got ", a].join("")); | |
} | |
return result; | |
} | |
function testAll() { | |
console.log("romanify: 1 -> I", shouldEqual(romanify(1), "I")); | |
console.log("romanify: 5 -> V", shouldEqual(romanify(5), "V")); | |
console.log("romanify: 10 -> X", shouldEqual(romanify(10), "X")); | |
console.log("romanify: 4 -> IV", shouldEqual(romanify(4), "IV")); | |
console.log("romanify: 6 -> VI", shouldEqual(romanify(6), "VI")); | |
console.log("romanify: 87 -> LXXXVII", shouldEqual(romanify(87), "LXXXVII")); | |
console.log("romanify: 147 -> CXLVII", shouldEqual(romanify(147), "CXLVII")); | |
console.log("romanify: 2487 -> MMCDLXXXVII", shouldEqual(romanify(2487), "MMCDLXXXVII")); | |
} | |
testAll(); | |
})(); |
Ah, that is a great consideration! I bundled the numbers and numerals together as an objects keys/values because I thought it improved readability.
So I could fix this in a few ways. The one I've implemented (and updated the gist with) is to use two arrays, one for numbers and one for corresponding numerals. This means my for-in loop changes to a for loop, I just output corresponding numerals using the same array index.
Other considerations were mainly around the structure of the numbers/numerals (a single array containing objects with a single key/value, or a single array containing arrays with two indexes), but I think I picked the most efficient one.
Cool, that does the trick! I hear what you're saying re: legibility of the object -- one other approach is to zip the two arrays together to make an array of tuples, ie var tuples = [["M", 1000], ["CM", 900]...]
and then iterate over these tuples. As to which is more legible, that's debatable :)
Nice, that's a good approach! The recursion certainly DRYs the code up.
Only one problem -- in JavaScript (and Ruby, not sure about Python), you are not guaranteed to get your object keys back in the order that you put them in. In other words, when you do
for (numeral in numerals)
you are not guaranteed to get "M" first, "CM" second, etc. How can you change the code to ensure that you will always loop through these values in the right order, no matter what browser/JS environment you're in?