RosettaCodeData/Task/Four-is-magic/JavaScript/four-is-magic-2.js

182 lines
5.5 KiB
JavaScript

const reverseOrderedNumberToTextMap = (function () {
const rawNumberToTextMapping = { // Ported over from the Python solution.
[1n]: "one",
[2n]: "two",
[3n]: "three",
[4n]: "four",
[5n]: "five",
[6n]: "six",
[7n]: "seven",
[8n]: "eight",
[9n]: "nine",
[10n]: "ten",
[11n]: "eleven",
[12n]: "twelve",
[13n]: "thirteen",
[14n]: "fourteen",
[15n]: "fifteen",
[16n]: "sixteen",
[17n]: "seventeen",
[18n]: "eighteen",
[19n]: "nineteen",
[20n]: "twenty",
[30n]: "thirty",
[40n]: "forty",
[50n]: "fifty",
[60n]: "sixty",
[70n]: "seventy",
[80n]: "eighty",
[90n]: "ninety",
[100n]: "hundred",
[1000n]: "thousand",
[10n ** 6n]: "million",
[10n ** 9n]: "billion",
[10n ** 12n]: "trillion",
[10n ** 15n]: "quadrillion",
[10n ** 18n]: "quintillion",
[10n ** 21n]: "sextillion",
[10n ** 24n]: "septillion",
[10n ** 27n]: "octillion",
[10n ** 30n]: "nonillion",
[10n ** 33n]: "decillion",
[10n ** 36n]: "undecillion",
[10n ** 39n]: "duodecillion",
[10n ** 42n]: "tredecillion",
[10n ** 45n]: "quattuordecillion",
[10n ** 48n]: "quinquadecillion",
[10n ** 51n]: "sedecillion",
[10n ** 54n]: "septendecillion",
[10n ** 57n]: "octodecillion",
[10n ** 60n]: "novendecillion",
[10n ** 63n]: "vigintillion",
[10n ** 66n]: "unvigintillion",
[10n ** 69n]: "duovigintillion",
[10n ** 72n]: "tresvigintillion",
[10n ** 75n]: "quattuorvigintillion",
[10n ** 78n]: "quinquavigintillion",
[10n ** 81n]: "sesvigintillion",
[10n ** 84n]: "septemvigintillion",
[10n ** 87n]: "octovigintillion",
[10n ** 90n]: "novemvigintillion",
[10n ** 93n]: "trigintillion",
[10n ** 96n]: "untrigintillion",
[10n ** 99n]: "duotrigintillion",
[10n ** 102n]: "trestrigintillion",
[10n ** 105n]: "quattuortrigintillion",
[10n ** 108n]: "quinquatrigintillion",
[10n ** 111n]: "sestrigintillion",
[10n ** 114n]: "septentrigintillion",
[10n ** 117n]: "octotrigintillion",
[10n ** 120n]: "noventrigintillion",
[10n ** 123n]: "quadragintillion",
[10n ** 153n]: "quinquagintillion",
[10n ** 183n]: "sexagintillion",
[10n ** 213n]: "septuagintillion",
[10n ** 243n]: "octogintillion",
[10n ** 273n]: "nonagintillion",
[10n ** 303n]: "centillion",
[10n ** 306n]: "uncentillion",
[10n ** 309n]: "duocentillion",
[10n ** 312n]: "trescentillion",
[10n ** 333n]: "decicentillion",
[10n ** 336n]: "undecicentillion",
[10n ** 363n]: "viginticentillion",
[10n ** 366n]: "unviginticentillion",
[10n ** 393n]: "trigintacentillion",
[10n ** 423n]: "quadragintacentillion",
[10n ** 453n]: "quinquagintacentillion",
[10n ** 483n]: "sexagintacentillion",
[10n ** 513n]: "septuagintacentillion",
[10n ** 543n]: "octogintacentillion",
[10n ** 573n]: "nonagintacentillion",
[10n ** 603n]: "ducentillion",
[10n ** 903n]: "trecentillion",
[10n ** 1203n]: "quadringentillion",
[10n ** 1503n]: "quingentillion",
[10n ** 1803n]: "sescentillion",
[10n ** 2103n]: "septingentillion",
[10n ** 2403n]: "octingentillion",
[10n ** 2703n]: "nongentillion",
[10n ** 3003n]: "millinillion"
};
return new Map(Object.entries(rawNumberToTextMapping)
.sort((a, b) => BigInt(a[0]) > BigInt(b[0]) ? -1 : 1)
.map(numberAndText => [BigInt(numberAndText[0]), numberAndText[1]]));
})();
function getCardinalRepresentation(number)
{
if (number == 0n)
{
return "zero";
}
function* generateCardinalRepresentationTokens(number)
{
if (number <= 0n)
{
yield "negative";
number *= -1n;
}
for (const [currentEntryNumber, currentEntryText] of reverseOrderedNumberToTextMap.entries())
{
if (number >= currentEntryNumber)
{
if (currentEntryNumber >= 100n)
{
yield* generateCardinalRepresentationTokens(number / currentEntryNumber);
}
yield currentEntryText;
number -= currentEntryNumber;
}
}
}
return [...generateCardinalRepresentationTokens(number)].join(" ");
}
function* generateFourIsMagicParts(number)
{
if (typeof number != "bigint")
{
number = BigInt(number);
}
if (number == 4n)
{
yield "four is magic";
}
else
{
const cardinalRepresentation = getCardinalRepresentation(number);
yield `${cardinalRepresentation} is ${getCardinalRepresentation(BigInt(cardinalRepresentation.length))}`;
yield* generateFourIsMagicParts(cardinalRepresentation.length);
}
}
function capitalizeFirstLetter(str)
{
return str.replace(/^([a-z])/, chr => chr.toUpperCase());
}
function fourIsMagic(number)
{
return capitalizeFirstLetter(`${[...generateFourIsMagicParts(number)].join(", ")}.`);
}
[
0,
-150,
210,
10n ** 2703n + 1225n,
4,
-4,
10n ** 3003n + 42n
].map(fourIsMagic).join("\n\n");