0

Roman numerals as values, not pass the input-output test at freecodecamp.com for converting decimal numbers to Roman numerals.

Why does the first code below, where the decimal numbers are used as keys and the Roman numerals as values, not pass the input-output test at freecodecamp.com for converting decimal numbers to Roman numerals? However, the second code, where the keys and values have switched places, does pass the test. The only difference between the two codes is the ordering of the keys and values in the romanNumerals object.

Why does this seemingly simple change affect the test results?

The first code for converting decimal numbers to Roman numerals only work correctly for the inputs convertToRoman(2) and convertToRoman(3), but fails for other input numbers such as 4, 5, 9, 12, 16, etc.? Despite seemingly correct logic and loop iterations, it produces incorrect results for various input values.

What could be causing this issue specifically for the mentioned input numbers, and how can it be resolved?

1.

function convertToRoman(num) {
  const romanNumerals = {
    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"
  };

  let roman = "";
  let restartLoop = false;

  do {
    restartLoop = false;

    for (let key in romanNumerals) {
      if (num >= key) {
        roman += romanNumerals[key];
        num -= key;
        restartLoop = true;
        break;
      }
    }
  } while (restartLoop);

  return roman;
}

console.log(convertToRoman(3))
console.log(convertToRoman(4))
console.log(convertToRoman(23))

2.

function convertToRoman(num) {
  const romanNumerals = {
    "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
  };

  let roman = "";
  let restartLoop = false;

  do {
    restartLoop = false;

    for (let key in romanNumerals) {
      if (num >= romanNumerals[key]) {
        roman += key;
        num -= romanNumerals[key];
        restartLoop = true;
        break;
      }
    }
  } while (restartLoop);

  return roman;
}

console.log(convertToRoman(3))
console.log(convertToRoman(4))
console.log(convertToRoman(23))
mplungjan
  • 169,008
  • 28
  • 173
  • 236
simLight
  • 11
  • 2
  • 1
    The order of the keys is important for the algorithm and different in both codes. Numerical keys are iterated in numerical order and alphanumerical keys are iterated in insertion order, if I remember correctly. – jabaa May 31 '23 at 13:53
  • `console.log(romanNumerals)` would have given you one clue what was going on. – epascarello May 31 '23 at 14:31

1 Answers1

1

When you're assigning values to numeral keys, looping through them returns them sorted. This is part of the specification:

The traversal order, as of modern ECMAScript specification, is well-defined and consistent across implementations. Within each component of the prototype chain, all non-negative integer keys (those that can be array indices) will be traversed first in ascending order by value, then other string keys in ascending chronological order of property creation. source

const highToLow = {
  5: 'five',
  4: 'four',
  3: 'three'
}

console.log(highToLow);

So basically you're reversing the whole order of your object and number 1 (the I) comes first.

I would suggest keeping the second example of your code, because that one will always work, regardless of values added to the object.

Douwe de Haan
  • 6,247
  • 1
  • 30
  • 45
  • You should answer the whole question. You forgot: _"how can it be resolved?"_ – jabaa May 31 '23 at 14:00
  • @jabaa I would suggest using the second example OP showed which is working ;) That's basically the best way to fix his code. But I'll add it to my answer! – Douwe de Haan May 31 '23 at 14:02
  • Obviously, the second example isn't considered as result, otherwise the OP wouldn't ask for a solution in the same question where they posted the code ;) – jabaa May 31 '23 at 16:24
  • I didn't know that the looping automatically sorted the objects in numerical order, starting from the smallest. So, many thanks for that. I understood that the solution was to use "Object.keys" to get an array of the keys and then sort that array in descending order (b - a). Then it would work with the first code. – simLight Jun 01 '23 at 15:20