package say import "strings" var small = []string{ "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", } var tens = []string{ "", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety", } var scale = []string{ "", "thousand", "million", "billion", "trillion", "quadrillion", "quintillion", } type Group struct { Value uint64 Power int } func (g Group) String() string { var s []string if h := g.Value / 100; h > 0 { s = append(s, small[h]+" hundred") } if t := g.Value % 100; t > 0 { if tns := t / 10; tns >= 2 { if sml := t % 10; sml > 0 { s = append(s, tens[tns]+"-"+small[sml]) } else { s = append(s, tens[tns]) } } else if t > 0 { s = append(s, small[t]) } } if p := scale[g.Power]; p != "" && len(s) > 0 { s = append(s, p) } return strings.Join(s, " ") } func split(n uint64) []Group { var g []Group for i := 0; n > 0; i++ { r := n % 1e3 n /= 1e3 g = append(g, Group{ Value: r, Power: i, }) } return g } func Say(n uint64) string { if n <= 0 { return "zero" } g := split(n) var s []string for i := len(g) - 1; i >= 0; i-- { if str := g[i].String(); str != "" { s = append(s, str) } } return strings.Join(s, " ") }