summaryrefslogtreecommitdiff
path: root/go/say/say.go
diff options
context:
space:
mode:
Diffstat (limited to 'go/say/say.go')
-rw-r--r--go/say/say.go74
1 files changed, 74 insertions, 0 deletions
diff --git a/go/say/say.go b/go/say/say.go
new file mode 100644
index 0000000..4fdc5b4
--- /dev/null
+++ b/go/say/say.go
@@ -0,0 +1,74 @@
+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, " ")
+}