Reputation: 392
I am trying to get an integer to Roman Numeral function to work. It does work, but what it's returning gets so weird at the end. I know that it has something to do with recursion, but I can't tell what.
the returned value at the end goes from
MMCCCXXVIII -
MMCCCXXVII -
MMCCCXXVI -
MMCCCXXV -
MMCCCXX -
MMCCCX -
MMCCC -
MMCC-
MM-
M
function romanToInt(int, rom = '') {
function binarySearch(arr, q, rom, le, ri) {
// set left right middle
let l = le || 0,
r = ri || arr.length - 1,
m = Math.floor((r + l) / 2);
// check if the middle is q
if (arr[m] === q) {
return m;
}
if (arr[l] === q) {
return l;
}
if (arr[r] === q) {
return r;
}
if (q > arr[m] && m + 1 < r) {
return binarySearch(arr, q, rom, m, ri);
}
if (q < arr[m] && m - 1 > l) {
return binarySearch(arr, q, rom, le, m);
}
let numToUse = '0';
let lTemp = 500000000000000000000000000000,
rTemp = 500000000000000000000000000000,
mTemp = 500000000000000000000000000000;
if (arr[l] - q < 0) {
lTemp = Math.abs(arr[l] - q);
}
if (arr[m] - q < 0) {
mTemp = Math.abs(arr[m] - q);
}
if (arr[r] - q < 0) {
rTemp = Math.abs(arr[r] - q);
}
let tempToFind = Math.min(lTemp, mTemp, rTemp);
if (lTemp === tempToFind) {
return l;
}
if (rTemp === tempToFind) {
return r;
}
if (mTemp === tempToFind) {
return m;
}
return `pending`;
}
let convArr = [
[1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000],
['I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M'],
],
romanNumeral = rom;
let returnedVal = binarySearch(convArr[0], int);
romanNumeral = romanNumeral + convArr[1][returnedVal];
let newQ = int - convArr[0][returnedVal];
if (newQ === 0) {
return romanNumeral;
} else {
romanToInt(newQ, romanNumeral);
}
return romanNumeral;
}
const rom = 2328;
console.log(romanToInt(rom));
Upvotes: 0
Views: 869
Reputation: 22247
Not sure about the binary search. This is a slightly different recursive approach,.
const numberToRoman = (num, rom = "") => {
if (num === 0) return rom;
for (var i = convArr[0].length - 1; i >= 0; i--) {
if (num >= convArr[0][i]) {
return numberToRoman(num - convArr[0][i], rom + convArr[1][i]);
}
}
};
const convArr = [
[1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000],
['I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M'],
];
const someNumber = 2328;
console.log(numberToRoman(someNumber));
Upvotes: 1
Reputation: 21130
You forgot to return
the recursive return value.
if (newQ === 0) {
return romanNumeral;
} else {
romanToInt(newQ, romanNumeral);
}
return romanNumeral;
Should be:
if (newQ === 0) {
return romanNumeral;
} else {
return romanToInt(newQ, romanNumeral); // <- return the recursive result
}
// or use a guard clause
if (newQ === 0) return romanNumeral;
return romanToInt(newQ, romanNumeral)
function romanToInt(int, rom = '') {
function binarySearch(arr, q, rom, le, ri) {
// set left right middle
let l = le || 0,
r = ri || arr.length - 1,
m = Math.floor((r + l) / 2);
// check if the middle is q
if (arr[m] === q) {
return m;
}
if (arr[l] === q) {
return l;
}
if (arr[r] === q) {
return r;
}
if (q > arr[m] && m + 1 < r) {
return binarySearch(arr, q, rom, m, ri);
}
if (q < arr[m] && m - 1 > l) {
return binarySearch(arr, q, rom, le, m);
}
let numToUse = '0';
let lTemp = 500000000000000000000000000000,
rTemp = 500000000000000000000000000000,
mTemp = 500000000000000000000000000000;
if (arr[l] - q < 0) {
lTemp = Math.abs(arr[l] - q);
}
if (arr[m] - q < 0) {
mTemp = Math.abs(arr[m] - q);
}
if (arr[r] - q < 0) {
rTemp = Math.abs(arr[r] - q);
}
let tempToFind = Math.min(lTemp, mTemp, rTemp);
if (lTemp === tempToFind) {
return l;
}
if (rTemp === tempToFind) {
return r;
}
if (mTemp === tempToFind) {
return m;
}
return `pending`;
}
let convArr = [
[1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000],
['I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M'],
],
romanNumeral = rom;
let returnedVal = binarySearch(convArr[0], int);
romanNumeral = romanNumeral + convArr[1][returnedVal];
let newQ = int - convArr[0][returnedVal];
if (newQ === 0) {
return romanNumeral;
} else {
return romanToInt(newQ, romanNumeral); // <- return the recursive result
}
}
const rom = 2328;
console.log(romanToInt(rom));
Upvotes: 1