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) } }