-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoracle.go
110 lines (93 loc) · 2.67 KB
/
oracle.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Stefan Nilsson 2013-03-13
// This program implements an ELIZA-like oracle (en.wikipedia.org/wiki/ELIZA).
package main
import (
"bufio"
"fmt"
"math/rand"
"os"
"strings"
"time"
)
const (
star = "Pythia"
venue = "Delphi"
prompt = "> "
)
func main() {
fmt.Printf("Welcome to %s, the oracle at %s.\n", star, venue)
fmt.Println("Your questions will be answered in due time.")
questions := Oracle()
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print(prompt)
line, _ := reader.ReadString('\n')
line = strings.TrimSpace(line)
if line == "" {
continue
}
fmt.Printf("%s heard: %s\n", star, line)
questions <- line // The channel doesn't block.
}
}
// Oracle returns a channel on which you can send your questions to the oracle.
// You may send as many questions as you like on this channel, it never blocks.
// The answers arrive on stdout, but only when the oracle so decides.
// The oracle also prints sporadic prophecies to stdout even without being asked.
func Oracle() chan<- string {
questions := make(chan string)
answers := make(chan string)
go answerQuestions(questions, answers)
go generateProphecies(answers)
go printAnswers(answers)
return questions
}
func answerQuestions(questions <-chan string, answers chan<- string) {
for q := range questions {
go func() {
prophecy(q, answers)
}()
}
}
func generateProphecies(answers chan<- string) {
time.Sleep(time.Duration(rand.Intn(3)+10) * time.Second)
stuff := []string{
"Your mind is hard to read",
"Your future looks bright",
"Im not feeling the connection",
"Im not feeling the connection",
"Your inner is hard to decipher",
}
answers <- stuff[rand.Intn(len(stuff))]
generateProphecies(answers)
}
func printAnswers(ch <-chan string) {
for answer := range ch {
fmt.Printf("%s: %s\n", star, answer)
}
}
// This is the oracle's secret algorithm.
// It waits for a while and then sends a message on the answer channel.
func prophecy(question string, answer chan<- string) {
// Keep them waiting. Pythia, the original oracle at Delphi,
// only gave prophecies on the seventh day of each month.
time.Sleep(time.Duration(2+rand.Intn(3)) * time.Second)
// Find the longest word.
longestWord := ""
words := strings.Fields(question) // Fields extracts the words into a slice.
for _, w := range words {
if len(w) > len(longestWord) {
longestWord = w
}
}
// Cook up some pointless nonsense.
nonsense := []string{
"The moon is dark.",
"The sun is bright.",
}
answer <- longestWord + "... " + nonsense[rand.Intn(len(nonsense))]
}
func init() { // Functions called "init" are executed before the main function.
// Use new pseudo random numbers every time.
rand.Seed(time.Now().Unix())
}