numToLez = '''(input_text) => { const million = 1e6; // 10^6; const billion = 1e9; // 10^9; const trillion = 1e12; // 10^12; const quadrillion = 1e15; // 10^15; const quintillion = 1e18; // 10^18; const sextillion = 1e21; // 10^21; const septillion = 1e24; // 10^24; const octillion = 1e27; // 10^27; const nonillion = 1e30; // 10^30; const atomic = { 0: 'нул', 1: 'сад', 2: 'кьвед', 3: 'пуд', 4: 'кьуд', 5: 'вад', 6: 'ругуд', 7: 'ирид', 8: 'муьжуьд', 9: 'кIуьд', 10: 'цIуд', 20: 'къад', 40: 'яхцIур', // 10^2 100: 'виш', // 10^3 1000: 'агъзур', // 10^6 [million]: 'миллион', // 10^9 [billion]: 'миллиард', // 10^12 [trillion]: 'триллион', // 10^15 [quadrillion]: 'квадриллион', // 10^18 [quintillion]: 'квинтиллион', // 10^21 [sextillion]: 'секстиллион', // 10^24 [septillion]: 'септиллион', // 10^27 [octillion]: 'октиллион', // 10^30 [nonillion]: 'нониллион', }; const MINUS = 'минус'; function separateNumberIntoUnits(n) { if (n == 0) return [0]; const arr = []; let i = 1; while (n > 0) { arr.unshift((n % 10) * i); n = Math.floor(n / 10); i *= 10; } const result = groupNumberUnitsToLezgiRange(arr); return result; } const ranges = [ { start: nonillion, end: octillion }, // nonillion to octillion { start: octillion, end: septillion }, // octillion to septillion { start: septillion, end: sextillion }, // septillion to sextillion { start: sextillion, end: quintillion }, // sextillion to quintillion { start: quadrillion, end: quintillion }, // quadrillion to quintillion { start: trillion, end: quadrillion }, // trillion to quadrillion { start: billion, end: trillion }, // billion to trillion { start: million, end: billion }, // million to billion { start: 1000, end: million }, // thousand to million ]; function groupNumberUnitsToLezgiRange(arr) { let result = []; for (let range of ranges) { let sum = arr.reduce((acc, num) => { if (num >= range.start && num < range.end) { return acc + num; } return acc; }, 0); if (sum !== 0) { result.push(sum); } // Filter out the numbers that were added to sum arr = arr.filter((num) => num < range.start || num >= range.end); } // Concatenate the remaining numbers to the result result = result.concat(arr); return result; } function getTenPlusBase(num) { if (num < 10 || num >= 20) { throw new Error('Invalid number'); } if (num === 10) { return [atomic[10]]; } const base10 = atomic[10].slice(0, -2); if (num === 11 || num === 15 || num === 16) { return [base10 + 'у']; } else if (num < 15) { return [base10 + 'и']; } return [base10 + 'е']; } function getTwentyPlusBase(num) { return num === 20 ? [atomic[20]] : ['къанни']; } function getThirtyPlusBase(num) { return [...getTwentyPlusBase(num), ...getTenPlusBase(num - 20)]; } function getFourtyPlusBase(num) { return num === 40 ? [atomic[40]] : [atomic[40], 'ни']; } function getFiftyPlusBase(num) { return [...getFourtyPlusBase(num), ...getTenPlusBase(num - 40)]; } function getSixtyPlusBase(num) { return num === 60 ? [atomic[3], atomic[20]] : [atomic[3], ...getTwentyPlusBase(num)]; } function getSeventyPlusBase(num) { return [...getSixtyPlusBase(61), ...getTenPlusBase(num - 60)]; } function getEightyPlusBase(num) { return num === 80 ? [atomic[4], atomic[20]] : [atomic[4], ...getTwentyPlusBase(num)]; } function getNinetyPlusBase(num) { return [...getEightyPlusBase(81), ...getTenPlusBase(num - 80)]; } function getHundredPlusBase(num) { return num % 100 === 0 ? [atomic[100]] : [atomic[100], 'ни']; } function getHundredPlusNumCount(numCount) { if (atomic[numCount] !== undefined) { return numCount === 2 ? [atomic[numCount].slice(0, -1)] : [atomic[numCount]]; } return undefined; } function getBetweenHundredAndThousand(num, followUpNumber) { const hundredsCount = num % 100 != 0 ? num - (num % 100) : num / 100; const hundredsCountInLezgi = getHundredPlusNumCount(hundredsCount); return [...hundredsCountInLezgi, ' ', ...getHundredPlusBase(num + followUpNumber)]; } function getThousandPlusBase(num) { return num % 1000 === 0 ? [atomic[1000]] : [atomic[1000], 'ни']; } function getBetweenThousandAndMillion(num, followUpNumber) { var _a; const thousandsCount = num % 1000 != 0 ? num - (num % 1000) : num / 1000; const thousandsCountInLezgi = (_a = getHundredPlusNumCount(thousandsCount)) !== null && _a !== void 0 ? _a : getCompound(thousandsCount); return [...thousandsCountInLezgi, ' ', ...getThousandPlusBase(num + followUpNumber)]; } function getMillionPlusBase(num) { return num % million === 0 ? [atomic[million]] : [atomic[million], 'ни']; } function getBetweenMillionAndBillion(num, followUpNumber) { var _a; const millionsCount = num % million != 0 ? num - (num % million) : num / million; const millionsCountInLezgi = (_a = getHundredPlusNumCount(millionsCount)) !== null && _a !== void 0 ? _a : getCompound(millionsCount); return [...millionsCountInLezgi, ' ', ...getMillionPlusBase(num + followUpNumber)]; } function getBillionPlusBase(num) { return num % billion === 0 ? [atomic[billion]] : [atomic[billion], 'ни']; } function getBetweenBillionAndTrillion(num, followUpNumber) { var _a; const billionsCount = num % billion != 0 ? num - (num % billion) : num / billion; const billionsCountInLezgi = (_a = getHundredPlusNumCount(billionsCount)) !== null && _a !== void 0 ? _a : getCompound(billionsCount); return [...billionsCountInLezgi, ' ', ...getBillionPlusBase(num + followUpNumber)]; } function getTrillionPlusBase(num) { return num % trillion === 0 ? [atomic[trillion]] : [atomic[trillion], 'ни']; } function getBetweenTrillionAndQuadrillion(num, followUpNumber) { var _a; const trillionsCount = num % trillion != 0 ? num - (num % trillion) : num / trillion; const trillionsCountInLezgi = (_a = getHundredPlusNumCount(trillionsCount)) !== null && _a !== void 0 ? _a : getCompound(trillionsCount); return [...trillionsCountInLezgi, ' ', ...getTrillionPlusBase(num + followUpNumber)]; } function getQuadrillionPlusBase(num) { return num % quadrillion === 0 ? [atomic[quadrillion]] : [atomic[quadrillion], 'ни']; } function getBetweenQuadrillionAndQuintillion(num, followUpNumber) { var _a; const quadrillionsCount = num % quadrillion != 0 ? num - (num % quadrillion) : num / quadrillion; const quadrillionsCountInLezgi = (_a = getHundredPlusNumCount(quadrillionsCount)) !== null && _a !== void 0 ? _a : getCompound(quadrillionsCount); return [...quadrillionsCountInLezgi, ' ', ...getQuadrillionPlusBase(num + followUpNumber)]; } function getQuintillionPlusBase(num) { return num % quintillion === 0 ? [atomic[quintillion]] : [atomic[quintillion], 'ни']; } function getBetweenQuintillionAndSextillion(num, followUpNumber) { var _a; const quintillionsCount = num % quintillion != 0 ? num - (num % quintillion) : num / quintillion; const quintillionsCountInLezgi = (_a = getHundredPlusNumCount(quintillionsCount)) !== null && _a !== void 0 ? _a : getCompound(quintillionsCount); return [...quintillionsCountInLezgi, ' ', ...getQuintillionPlusBase(num + followUpNumber)]; } function getSextillionPlusBase(num) { return num % sextillion === 0 ? [atomic[sextillion]] : [atomic[sextillion], 'ни']; } function getBetweenSextillionAndSeptillion(num, followUpNumber) { var _a; const sextillionsCount = num % sextillion != 0 ? num - (num % sextillion) : num / sextillion; const sextillionsCountInLezgi = (_a = getHundredPlusNumCount(sextillionsCount)) !== null && _a !== void 0 ? _a : getCompound(sextillionsCount); return [...sextillionsCountInLezgi, ' ', ...getSextillionPlusBase(num + followUpNumber)]; } function getSeptillionPlusBase(num) { return num % septillion === 0 ? [atomic[septillion]] : [atomic[septillion], 'ни']; } function getBetweenSeptillionAndOctillion(num, followUpNumber) { var _a; const septillionsCount = num % septillion != 0 ? num - (num % septillion) : num / septillion; const septillionsCountInLezgi = (_a = getHundredPlusNumCount(septillionsCount)) !== null && _a !== void 0 ? _a : getCompound(septillionsCount); return [...septillionsCountInLezgi, ' ', ...getSeptillionPlusBase(num + followUpNumber)]; } function getOctillionPlusBase(num) { return num % octillion === 0 ? [atomic[octillion]] : [atomic[octillion], 'ни']; } function getBetweenOctillionAndNonillion(num, followUpNumber) { var _a; const octillionsCount = num % octillion != 0 ? num - (num % octillion) : num / octillion; const octillionsCountInLezgi = (_a = getHundredPlusNumCount(octillionsCount)) !== null && _a !== void 0 ? _a : getCompound(octillionsCount); return [...octillionsCountInLezgi, ' ', ...getOctillionPlusBase(num + followUpNumber)]; } function getNonillionPlusBase(num) { return num % nonillion === 0 ? [atomic[nonillion]] : [atomic[nonillion], 'ни']; } function getCompound(num) { const units = separateNumberIntoUnits(num); const result = units.map((unit, i) => { if (i > 0 && unit === 7 && (units[i - 1] === 10 || units[i - 1] === 30 || units[i - 1] === 50 || units[i - 1] === 70 || units[i - 1] === 90)) { return [atomic[7].slice(1)]; } const followUpNumber = units.slice(i + 1).reduce((acc, num) => acc + num, 0); if (unit === 10) { return getTenPlusBase(unit + followUpNumber); } if (unit === 20) { return getTwentyPlusBase(unit + followUpNumber); } if (unit === 30) { return getThirtyPlusBase(unit + followUpNumber); } if (unit === 40) { return getFourtyPlusBase(unit + followUpNumber); } if (unit === 50) { return getFiftyPlusBase(unit + followUpNumber); } if (unit === 60) { return getSixtyPlusBase(unit + followUpNumber); } if (unit === 70) { return getSeventyPlusBase(unit + followUpNumber); } if (unit === 80) { return getEightyPlusBase(unit + followUpNumber); } if (unit === 90) { return getNinetyPlusBase(unit + followUpNumber); } if (unit === 100) { return getHundredPlusBase(unit + followUpNumber); } if (unit > 100 && unit < 1000) { return getBetweenHundredAndThousand(unit, followUpNumber); } if (unit === 1000) { return getThousandPlusBase(unit + followUpNumber); } if (unit > 1000 && unit < million) { return getBetweenThousandAndMillion(unit, followUpNumber); } if (unit === million) { return getMillionPlusBase(unit + followUpNumber); } if (unit > million && unit < billion) { return getBetweenMillionAndBillion(unit, followUpNumber); } if (unit === billion) { return getBillionPlusBase(unit + followUpNumber); } if (unit > billion && unit < trillion) { return getBetweenBillionAndTrillion(unit, followUpNumber); } if (unit === trillion) { return getTrillionPlusBase(unit + followUpNumber); } if (unit > trillion && unit < quadrillion) { return getBetweenTrillionAndQuadrillion(unit, followUpNumber); } if (unit === quadrillion) { return getQuadrillionPlusBase(unit + followUpNumber); } if (unit > quadrillion && unit < quintillion) { return getBetweenQuadrillionAndQuintillion(unit, followUpNumber); } if (unit === quintillion) { return getQuintillionPlusBase(unit + followUpNumber); } if (unit > quintillion && unit < sextillion) { return getBetweenQuintillionAndSextillion(unit, followUpNumber); } if (unit === sextillion) { return getSextillionPlusBase(unit + followUpNumber); } if (unit > sextillion && unit < septillion) { return getBetweenSextillionAndSeptillion(unit, followUpNumber); } if (unit === septillion) { return getSeptillionPlusBase(unit + followUpNumber); } if (unit > septillion && unit < octillion) { return getBetweenSeptillionAndOctillion(unit, followUpNumber); } if (unit === octillion) { return getOctillionPlusBase(unit + followUpNumber); } if (unit > octillion && unit < nonillion) { return getBetweenOctillionAndNonillion(unit, followUpNumber); } if (unit === nonillion) { return getNonillionPlusBase(unit + followUpNumber); } return units.length > 1 && unit === 0 ? [''] : [atomic[unit] || unit.toString()]; }); return result.flat(); //.join('').replaceAll(' ', ' ').trim(); } function getAtomicOrCompound(num) { if (atomic[num]) { return [atomic[num]]; } else { return getCompound(num); } } function numToLezgiArray(num) { if (isNaN(num)) { throw new Error('Provided value is not a number'); } if (!Number.isInteger(num)) { throw new Error('Provided number is not an integer. Currently only integers are supported!'); } const isNegative = num < 0; num = Math.abs(num); const result = getAtomicOrCompound(num) .filter((word) => word !== '') .map((word) => (word.endsWith('ни') ? [word, ' '] : word)) .flat(); return isNegative ? [MINUS, ' ', ...result] : result; } function numToLezgi(num) { const resultArray = numToLezgiArray(num); return (resultArray // .map((word) => (word.endsWith('ни') || word === MINUS ? word + ' ' : word)) .join('') .replaceAll(' ', ' ') .trim()); } function replaceNumbersWithWords(inputString) { return inputString.replaceAll(/\d+/g, (num) => numToLezgi(parseInt(num, 10))); } console.log(replaceNumbersWithWords(input_text)) return replaceNumbersWithWords(input_text) }'''