javascript – Algorithm for converting Arabic numerals into Roman numerals, without if

Question:

I came up with an algorithm for translating Arabic into Roman without if conditions.
I did not find analogues on the Internet. How do you like this option?

function myFunction()
{
  let r = [["I","V"],["X","L"],["C","D"],["M",""]];
  let f = [[],[[0,1,0]],[[0,2,0]],[[0,3,0]],[[0,1,1],[0,1,0]],[[0,1,1]],
          [[0,1,0],[0,1,1]],[[0,2,0],[0,1,1]],[[0,3,0],[0,1,1]],[[1,1,0],[0,1,0]]];
  let num = document.getElementById("num").value; let rim = "";

  String(num).split("").reverse().forEach((element, i) =>  
    	f[element].forEach((d) => 
  	     	rim = rim.concat (r[i+d[0]][d[2]].repeat(d[1]))));
      
  console.log(rim.split("").reverse().join(""));
}
Перевод арабские в римские
<input type="number" id="num">
<button onclick="myFunction()">Перевод</button>

Answer:

let num = "927";

The whole concept of the algorithm is based on the fact that if the number is divided into orders, then for each number in a separate order there will be the same substitution formula from Arabic to Roman.

So, for the number 927, we get 9 – third order, 2 – second order, 7 first order.

let m = [
    ["I","V"], // 1 порядок
    ["X","L"], // 2 порядок
    ["C","D"], // 3 порядок
    ["M",""]]; // 4 порядок

Further, if you take any number from any order, for 927 it is 9 or 2 or 7, or for any number from 1 to 9, then you can write universal formulas

More precisely, 9 universal formulas:

where P is the order of the number, r is the repetition (how many times this character should be repeated), and M is the first or second place in the order array

Then the formulas of numbers can be represented as:

1 - P.r(1).M(1)                 
2 - P.r(2).M(1)
3 - P.r(3).M(1)
4 - P.r(1).M(1) + P.r(1).M(2)
5 - P.r(1).M(2)
6 - P.r(1).M(2) + P.r(1).M(1)
7 - P.r(1).M(2) + P.r(2).M(1)
8 - P.r(1).M(2) + P.r(3).M(1)
9 - P.r(1).M(1) + P+1.r(1).M(1)

Our number 927 is converted by the formulas

9 (P=3) : P.r(1).M(1) + P+1.r(1).M(1), , состоит из двух частей
    1 часть: P.r(1).M(1), где P=3: ["C","D"], место 1, повторов 1. Значит: C
    2 часть: P+1.r(1).M(1), где P=4 (так как P+1): ["M",""], место 1, повторов 1, значит: M

2 (P=2) : P.r(2).M(1), где P=2: ["X","L"], место 1, повторов 2, значит: ХХ

7:(P=1) : P.r(1).M(2) + P.r(2).M(1), состоит из двух частей
        1 часть: P.r(1).M(2), где P=1: ["I","V"], место 2, повторов 1. Значит: V
        2 часть: P.r(2).M(1), где P=1: ["I","V"], место 1, повторов 2, значит: II

And now these formulas can be sewn into an array for each number. For example, for the number 6, this is the 6th element of the array f

[0,1,0], [0,1,1]  

That is, two elements
Where each part is a formula for a set of characters

First character: [0,1,0]

3 elements:

1 - порядок 
2 - количество повторов символа
3 - место в массиве "m" к примеру: ["X","L"] - 1 или 2 место

The formula itself works like this:

  1. split the number into an array of characters 927 -> [9,2,7]
  2. do the reverse [9,2,7]->[7,2,9], since the first order is relevant for the first element

  3. In the loop, we take a separate number 9, 2, or 7, by this number we take the formula in the f array, and use the second cycle to parse the group of formulas to take a separate block of the formula (for example, [0,1,0]), and this block will already tell us which character to take from the array "m", its place and the number of repetitions

     num.split("").reverse().forEach((e, i) => f[e].forEach((d) => r = r.concat (m[i+d[0]][d[2]].repeat(d[1]))));

    collect the string in reverse order and display the result.

     alert (r.split("").reverse().join(""));

Well, the unminified formula

num.split("").reverse().forEach((element, i) => 
{
    // element - элемент из числа 9 2 или 7
    formula = f[element];
    // для числа 7 = [[0,2,0],[0,1,1]]
    // тут 2 элемента массива по 3 числа, теперь нужно перебрать их

    formula.forEach((d) => 
    {
        // первый элемент для числа 7 - [0,2,0]
        // вытащим 3 элемента
        poradok = d[0];  // 0
        povtor = d[1];   // 2
        mesto = d[2];    // 0

        simbolMas = m[i+poradok]; // ["I","V"]
        findsimbol =  simbolMas[mesto] // "I"
        simbolRepeat = findsimbol.repeat(povtor); //  "II"  
        r = r.concat (  simbolRepeat ); // собираем строчку
    })
});
Scroll to Top