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:
- split the number into an array of characters 927 -> [9,2,7]
-
do the reverse [9,2,7]->[7,2,9], since the first order is relevant for the first element
-
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 ); // собираем строчку
})
});