182 lines
5.5 KiB
JavaScript
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");
|