school/cs235/lab07/fungulator/main.go

72 lines
1.7 KiB
Go

package main
import (
"bufio"
"fmt"
"math/rand"
"os"
"strings"
"time"
)
type LengthError struct {
Count int
}
func (e LengthError) Error() string {
return fmt.Sprintf("%d is not long enough (must be longer than 2)", e.Count)
}
func parse(words []string) (map[string][]string, string, error) {
if len(words) < 3 {
return nil, "", LengthError{len(words)}
}
mapping := make(map[string][]string)
var a, b, k, v, first_prefix string
for i := 0; i < len(words)-2; i++ {
a = words[i]
b = words[i+1]
k = fmt.Sprintf("%v %v", a, b)
if i == 0 {
first_prefix = k
}
v = words[i+2]
mapping[k] = append(mapping[k], v)
}
k = fmt.Sprintf("%v %v", words[len(words)-2], words[len(words)-1])
v = "THE_END"
mapping[k] = append(mapping[k], v)
return mapping, first_prefix, nil
}
func generateText(mapping map[string][]string, first_prefix string) string {
cur_prefix := first_prefix
output := first_prefix
for {
suffix := mapping[cur_prefix][rand.Intn(len(mapping[cur_prefix]))]
if suffix == "THE_END" {
break
}
output += fmt.Sprintf(" %v", suffix)
_prefix := strings.SplitN(cur_prefix, " ", 2)
cur_prefix = fmt.Sprintf("%v %v", _prefix[1], suffix)
}
return output
}
func main() {
rand.Seed(time.Now().UnixNano())
instream := bufio.NewReader(os.Stdin)
for s, err := instream.ReadBytes('\n'); err == nil; s, err = instream.ReadBytes('\n') {
words := strings.Fields(string(s))
mapping, first_prefix, err := parse(words)
var generated_text string
if err != nil {
generated_text = err.Error()
} else {
generated_text = generateText(mapping, first_prefix)
}
fmt.Printf("%v\n\t%v\n\t%v\n", words, mapping, generated_text)
}
}