|
This is a recursive number-to-words algorithm in TypeScript. It tries to be
straightforward and just uses if statements to make the logic a bit easier to
follow.
The key ideas are:
- Let the recursion do the work.
- Handle “and” carefully.
- Don’t move up in factors of ten; move up in word groups.
function numberToWords(num: number): string {
if (num < 0) {
return `minus ${numberToWords(-num)}`;
}
if (num in DIRECT) {
return DIRECT[num];
}
if (num < 100) {
const units = num % 10;
const tens = num - units;
return `${DIRECT[tens]} ${numberToWords(units)}`;
}
if (num < 1000) {
const sub_hundreds = num % 100;
const hundreds = (num - sub_hundreds) / 100;
let words = `${numberToWords(hundreds)} hundred`;
if (sub_hundreds) {
words += ` and ${numberToWords(sub_hundreds)}`;
}
return words;
}
if (num < 1000000) {
const sub_thous = num % 1000;
const thousands = (num - sub_thous) / 1000;
let words = `${numberToWords(thousands)} thousand`;
if (sub_thous) {
if (sub_thous < 100) {
words += " and";
}
words += ` ${numberToWords(sub_thous)}`;
}
return words;
}
if (num < 1000000000) {
const sub_mills = num % 1000000;
const millions = (num - sub_mills) / 1000000;
let words = `${numberToWords(millions)} million`;
if (sub_mills) {
if (sub_mills < 100) {
words += " and";
}
words += ` ${numberToWords(sub_mills)}`;
}
return words;
}
throw new Error("I can't count that high sorry");
}
Jest tests:
describe(numberToWords.name, () => {
test("convert number to English words", () => {
expect(numberToWords(-1)).toBe("minus one");
expect(numberToWords(0)).toBe("zero");
expect(numberToWords(1)).toBe("one");
expect(numberToWords(2)).toBe("two");
expect(numberToWords(3)).toBe("three");
expect(numberToWords(4)).toBe("four");
expect(numberToWords(5)).toBe("five");
expect(numberToWords(6)).toBe("six");
expect(numberToWords(7)).toBe("seven");
expect(numberToWords(8)).toBe("eight");
expect(numberToWords(9)).toBe("nine");
expect(numberToWords(10)).toBe("ten");
expect(numberToWords(11)).toBe("eleven");
expect(numberToWords(12)).toBe("twelve");
expect(numberToWords(13)).toBe("thirteen");
expect(numberToWords(14)).toBe("fourteen");
expect(numberToWords(15)).toBe("fifteen");
expect(numberToWords(16)).toBe("sixteen");
expect(numberToWords(17)).toBe("seventeen");
expect(numberToWords(18)).toBe("eighteen");
expect(numberToWords(19)).toBe("nineteen");
expect(numberToWords(20)).toBe("twenty");
expect(numberToWords(30)).toBe("thirty");
expect(numberToWords(40)).toBe("forty");
expect(numberToWords(50)).toBe("fifty");
expect(numberToWords(60)).toBe("sixty");
expect(numberToWords(70)).toBe("seventy");
expect(numberToWords(80)).toBe("eighty");
expect(numberToWords(90)).toBe("ninety");
expect(numberToWords(23)).toBe("twenty three");
expect(numberToWords(42)).toBe("forty two");
expect(numberToWords(88)).toBe("eighty eight");
expect(numberToWords(99)).toBe("ninety nine");
expect(numberToWords(100)).toBe("one hundred");
expect(numberToWords(200)).toBe("two hundred");
expect(numberToWords(300)).toBe("three hundred");
expect(numberToWords(400)).toBe("four hundred");
expect(numberToWords(500)).toBe("five hundred");
expect(numberToWords(600)).toBe("six hundred");
expect(numberToWords(700)).toBe("seven hundred");
expect(numberToWords(800)).toBe("eight hundred");
expect(numberToWords(900)).toBe("nine hundred");
expect(numberToWords(101)).toBe("one hundred and one");
expect(numberToWords(110)).toBe("one hundred and ten");
expect(numberToWords(119)).toBe("one hundred and nineteen");
expect(numberToWords(123)).toBe("one hundred and twenty three");
expect(numberToWords(250)).toBe("two hundred and fifty");
expect(numberToWords(999)).toBe("nine hundred and ninety nine");
expect(numberToWords(1000)).toBe("one thousand");
expect(numberToWords(1001)).toBe("one thousand and one");
expect(numberToWords(1010)).toBe("one thousand and ten");
expect(numberToWords(1100)).toBe("one thousand one hundred");
expect(numberToWords(1110)).toBe("one thousand one hundred and ten");
expect(numberToWords(1011)).toBe("one thousand and eleven");
expect(numberToWords(1111)).toBe("one thousand one hundred and eleven");
expect(numberToWords(5600)).toBe("five thousand six hundred");
expect(numberToWords(9099)).toBe("nine thousand and ninety nine");
expect(numberToWords(9999)).toBe(
"nine thousand nine hundred and ninety nine"
);
expect(numberToWords(10000)).toBe("ten thousand");
expect(numberToWords(20000)).toBe("twenty thousand");
expect(numberToWords(23000)).toBe("twenty three thousand");
expect(numberToWords(99999)).toBe(
"ninety nine thousand nine hundred and ninety nine"
);
expect(numberToWords(999999)).toBe(
"nine hundred and ninety nine thousand nine hundred and ninety nine"
);
expect(numberToWords(1000000)).toBe("one million");
expect(numberToWords(10000000)).toBe("ten million");
expect(numberToWords(100000000)).toBe("one hundred million");
expect(numberToWords(888888888)).toBe(
"eight hundred and eighty eight million eight hundred and eighty eight thousand eight hundred and eighty eight"
);
});
});
View post:
Straightforward recursive number-to-words algorithm in TypeScript
|
|
|
|