-
Notifications
You must be signed in to change notification settings - Fork 1
/
99-bottles-of-beer-2.go
80 lines (74 loc) · 2.12 KB
/
99-bottles-of-beer-2.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package main
import (
"fmt"
"math/rand"
"strings"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
for i := 99; i > 0; i-- {
fmt.Printf("%s %s %s\n",
slur(numberName(i), i),
pluralizeFirst(slur("bottle of", i), i),
slur("beer on the wall", i))
fmt.Printf("%s %s %s\n",
slur(numberName(i), i),
pluralizeFirst(slur("bottle of", i), i),
slur("beer", i))
fmt.Printf("%s %s %s\n",
slur("take one", i),
slur("down", i),
slur("pass it around", i))
fmt.Printf("%s %s %s\n",
slur(numberName(i-1), i),
pluralizeFirst(slur("bottle of", i), i-1),
slur("beer on the wall", i))
}
}
// adapted from Number names task
func numberName(n int) string {
switch {
case n < 0:
case n < 20:
return small[n]
case n < 100:
t := tens[n/10]
s := n % 10
if s > 0 {
t += " " + small[s]
}
return t
}
return ""
}
var small = []string{"no", "one", "two", "three", "four", "five", "six",
"seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen",
"fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}
var tens = []string{"ones", "ten", "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"}
// pluralize first word of s by adding an s, but only if n is not 1.
func pluralizeFirst(s string, n int) string {
if n == 1 {
return s
}
w := strings.Fields(s)
w[0] += "s"
return strings.Join(w, " ")
}
// p is string to slur, d is drunkenness, from 0 to 99
func slur(p string, d int) string {
// shuffle only interior letters
a := []byte(p[1 : len(p)-1])
// adapted from Knuth shuffle task.
// shuffle letters with probability d/100.
for i := len(a) - 1; i >= 1; i-- {
if rand.Intn(100) >= d {
j := rand.Intn(i + 1)
a[i], a[j] = a[j], a[i]
}
}
// condense spaces
w := strings.Fields(p[:1] + string(a) + p[len(p)-1:])
return strings.Join(w, " ")
}