172 lines
4.2 KiB
Go
172 lines
4.2 KiB
Go
// Embed embeds a noun phrase as the object of relative clause with a
|
|
// transitive verb.
|
|
//
|
|
// Argument relPhrase is a phrase with a relative clause, minus the object
|
|
// of the clause. That is, relPhrase consists of a subject, a relative
|
|
// pronoun, a transitive verb, possibly a preposition, but then no object.
|
|
//
|
|
// func Embed(relPhrase, nounPhrase string) string
|
|
|
|
// Verse generates a verse of a song with relative clauses that have
|
|
// a recursive structure.
|
|
//
|
|
// func Verse(subject string, relPhrases []string, nounPhrase string) string
|
|
//
|
|
// There are different ways to do this of course, but try using Embed as a
|
|
// subroutine and using programmatic recursion that reflects the grammatical
|
|
// recursion.
|
|
|
|
// Song generates the full text of "The House That Jack Built". Oh yes, you
|
|
// could just return a string literal, but humor us; use Verse as a subroutine.
|
|
//
|
|
// func Song() string
|
|
|
|
package house
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
var (
|
|
s = "This is"
|
|
r = []string{
|
|
"the cat that broke",
|
|
"the vase that was on",
|
|
}
|
|
p = "the shelf."
|
|
last = len(r) - 1
|
|
// song copied from readme
|
|
song = `This is the house that Jack built.
|
|
|
|
This is the malt
|
|
that lay in the house that Jack built.
|
|
|
|
This is the rat
|
|
that ate the malt
|
|
that lay in the house that Jack built.
|
|
|
|
This is the cat
|
|
that killed the rat
|
|
that ate the malt
|
|
that lay in the house that Jack built.
|
|
|
|
This is the dog
|
|
that worried the cat
|
|
that killed the rat
|
|
that ate the malt
|
|
that lay in the house that Jack built.
|
|
|
|
This is the cow with the crumpled horn
|
|
that tossed the dog
|
|
that worried the cat
|
|
that killed the rat
|
|
that ate the malt
|
|
that lay in the house that Jack built.
|
|
|
|
This is the maiden all forlorn
|
|
that milked the cow with the crumpled horn
|
|
that tossed the dog
|
|
that worried the cat
|
|
that killed the rat
|
|
that ate the malt
|
|
that lay in the house that Jack built.
|
|
|
|
This is the man all tattered and torn
|
|
that kissed the maiden all forlorn
|
|
that milked the cow with the crumpled horn
|
|
that tossed the dog
|
|
that worried the cat
|
|
that killed the rat
|
|
that ate the malt
|
|
that lay in the house that Jack built.
|
|
|
|
This is the priest all shaven and shorn
|
|
that married the man all tattered and torn
|
|
that kissed the maiden all forlorn
|
|
that milked the cow with the crumpled horn
|
|
that tossed the dog
|
|
that worried the cat
|
|
that killed the rat
|
|
that ate the malt
|
|
that lay in the house that Jack built.
|
|
|
|
This is the rooster that crowed in the morn
|
|
that woke the priest all shaven and shorn
|
|
that married the man all tattered and torn
|
|
that kissed the maiden all forlorn
|
|
that milked the cow with the crumpled horn
|
|
that tossed the dog
|
|
that worried the cat
|
|
that killed the rat
|
|
that ate the malt
|
|
that lay in the house that Jack built.
|
|
|
|
This is the farmer sowing his corn
|
|
that kept the rooster that crowed in the morn
|
|
that woke the priest all shaven and shorn
|
|
that married the man all tattered and torn
|
|
that kissed the maiden all forlorn
|
|
that milked the cow with the crumpled horn
|
|
that tossed the dog
|
|
that worried the cat
|
|
that killed the rat
|
|
that ate the malt
|
|
that lay in the house that Jack built.
|
|
|
|
This is the horse and the hound and the horn
|
|
that belonged to the farmer sowing his corn
|
|
that kept the rooster that crowed in the morn
|
|
that woke the priest all shaven and shorn
|
|
that married the man all tattered and torn
|
|
that kissed the maiden all forlorn
|
|
that milked the cow with the crumpled horn
|
|
that tossed the dog
|
|
that worried the cat
|
|
that killed the rat
|
|
that ate the malt
|
|
that lay in the house that Jack built.`
|
|
)
|
|
|
|
func TestEmbed(t *testing.T) {
|
|
l := r[last]
|
|
want := l + " " + p
|
|
if e := Embed(l, p); e != want {
|
|
t.Fatalf("Embed(%q, %q) = %q, want %q.", l, p, e, want)
|
|
}
|
|
}
|
|
|
|
func TestVerse(t *testing.T) {
|
|
for i := len(r); i >= 0; i-- {
|
|
ri := r[i:]
|
|
want := s + " " + strings.Join(append(ri, p), " ")
|
|
if v := Verse(s, ri, p); v != want {
|
|
t.Fatalf("Verse(%q, %q, %q) = %q, want %q.", s, ri, p, v, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSong(t *testing.T) {
|
|
s := Song()
|
|
if s == song {
|
|
return
|
|
}
|
|
fmt.Print(s)
|
|
// a little help in locating an error
|
|
got := strings.Split(s, "\n")
|
|
want := strings.Split(song, "\n")
|
|
var g, w string
|
|
var i int
|
|
for i, w = range want {
|
|
if len(got) <= i {
|
|
g = ""
|
|
break
|
|
}
|
|
if g = got[i]; g != w {
|
|
break
|
|
}
|
|
}
|
|
t.Fatalf("Song() line %d = %q, want %q", i+1, g, w)
|
|
}
|