package main
import (
"fmt"
"strings"
)
/*
Convert numbers to English words in Go
--------------------------------------
Supports numbers from 0 to 999,999,999,999,999.
Strategy:
- Break the number into named groups: trillions, billions, millions,
thousands, hundreds.
- Convert each 0–999 group using a helper function.
- Append group names ("trillion", "billion", etc.) when needed.
- Build the final string using strings.Builder for efficiency.
*/
var ones []string = []string{
"zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen",
}
var tensWords []string = []string{
"", "", "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety",
}
/*
appendWord:
Adds a word to the output builder with proper spacing.
*/
func appendWord(out *strings.Builder, word string) {
if word == "" {
return
}
if out.Len() > 0 {
out.WriteByte(' ')
}
out.WriteString(word)
}
/*
convertHundreds:
Converts numbers from 0 to 999 into words.
*/
func convertHundreds(n int64, out *strings.Builder) {
if n == 0 {
return
}
if n >= 100 {
appendWord(out, ones[n/100])
appendWord(out, "hundred")
n %= 100
if n > 0 {
appendWord(out, "and")
}
}
if n >= 20 {
appendWord(out, tensWords[n/10])
if n%10 != 0 {
appendWord(out, ones[n%10])
}
} else if n > 0 {
appendWord(out, ones[n])
}
}
/*
numberToWords:
Converts any number from 0 to 999,999,999,999,999 into English words.
*/
func numberToWords(num int64) string {
if num == 0 {
return "zero"
}
var out strings.Builder
var trillions int64 = num / 1_000_000_000_000
var billions int64 = (num / 1_000_000_000) % 1000
var millions int64 = (num / 1_000_000) % 1000
var thousands int64 = (num / 1_000) % 1000
var hundreds int64 = num % 1000
if trillions > 0 {
convertHundreds(trillions, &out)
appendWord(&out, "trillion")
}
if billions > 0 {
convertHundreds(billions, &out)
appendWord(&out, "billion")
}
if millions > 0 {
convertHundreds(millions, &out)
appendWord(&out, "million")
}
if thousands > 0 {
convertHundreds(thousands, &out)
appendWord(&out, "thousand")
}
if hundreds > 0 {
convertHundreds(hundreds, &out)
}
return out.String()
}
/*
main:
Demonstrates usage with multiple test numbers.
*/
func main() {
var tests []int64 = []int64{
1_234,
12_345,
123_456,
1_234_567,
123_456_789,
12_345_678_901,
1_234_567_890_123,
999_999_999_999_999,
}
for _, n := range tests {
fmt.Printf("%d -> %s\n", n, numberToWords(n))
}
}
/*
run:
1234 -> one thousand two hundred and thirty four
12345 -> twelve thousand three hundred and forty five
123456 -> one hundred and twenty three thousand four hundred and fifty six
1234567 -> one million two hundred and thirty four thousand five hundred and sixty seven
123456789 -> one hundred and twenty three million four hundred and fifty six thousand seven hundred and eighty nine
12345678901 -> twelve billion three hundred and forty five million six hundred and seventy eight thousand nine hundred and one
1234567890123 -> one trillion two hundred and thirty four billion five hundred and sixty seven million eight hundred and ninety thousand one hundred and twenty three
999999999999999 -> nine hundred and ninety nine trillion nine hundred and ninety nine billion nine hundred and ninety nine million nine hundred and ninety nine thousand nine hundred and ninety nine
*/