Initial Commit
This commit is contained in:
80
go/food-chain/README.md
Normal file
80
go/food-chain/README.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Food Chain
|
||||
|
||||
Write a program that generates the lyrics of the song 'I Know an Old Lady Who Swallowed a Fly'
|
||||
|
||||
Write a program that generates the lyrics to the song
|
||||
"I know an old lady who swallowed a fly". While you could
|
||||
copy/paste the lyrics, or read them from a file, this
|
||||
problem is much more interesting if you approach it
|
||||
algorithmically.
|
||||
|
||||
This is a [cumulative song](http://en.wikipedia.org/wiki/Cumulative_song) of unknown origin.
|
||||
|
||||
This is one of many common variants.
|
||||
|
||||
```plain
|
||||
I know an old lady who swallowed a fly.
|
||||
I don't know why she swallowed the fly. Perhaps she'll die.
|
||||
|
||||
I know an old lady who swallowed a spider.
|
||||
It wriggled and jiggled and tickled inside her.
|
||||
She swallowed the spider to catch the fly.
|
||||
I don't know why she swallowed the fly. Perhaps she'll die.
|
||||
|
||||
I know an old lady who swallowed a bird.
|
||||
How absurd to swallow a bird!
|
||||
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
|
||||
She swallowed the spider to catch the fly.
|
||||
I don't know why she swallowed the fly. Perhaps she'll die.
|
||||
|
||||
I know an old lady who swallowed a cat.
|
||||
Imagine that, to swallow a cat!
|
||||
She swallowed the cat to catch the bird.
|
||||
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
|
||||
She swallowed the spider to catch the fly.
|
||||
I don't know why she swallowed the fly. Perhaps she'll die.
|
||||
|
||||
I know an old lady who swallowed a dog.
|
||||
What a hog, to swallow a dog!
|
||||
She swallowed the dog to catch the cat.
|
||||
She swallowed the cat to catch the bird.
|
||||
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
|
||||
She swallowed the spider to catch the fly.
|
||||
I don't know why she swallowed the fly. Perhaps she'll die.
|
||||
|
||||
I know an old lady who swallowed a goat.
|
||||
Just opened her throat and swallowed a goat!
|
||||
She swallowed the goat to catch the dog.
|
||||
She swallowed the dog to catch the cat.
|
||||
She swallowed the cat to catch the bird.
|
||||
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
|
||||
She swallowed the spider to catch the fly.
|
||||
I don't know why she swallowed the fly. Perhaps she'll die.
|
||||
|
||||
I know an old lady who swallowed a cow.
|
||||
I don't know how she swallowed a cow!
|
||||
She swallowed the cow to catch the goat.
|
||||
She swallowed the goat to catch the dog.
|
||||
She swallowed the dog to catch the cat.
|
||||
She swallowed the cat to catch the bird.
|
||||
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
|
||||
She swallowed the spider to catch the fly.
|
||||
I don't know why she swallowed the fly. Perhaps she'll die.
|
||||
|
||||
I know an old lady who swallowed a horse.
|
||||
She's dead, of course!
|
||||
```
|
||||
|
||||
To run the tests simply run the command `go test` in the exercise directory.
|
||||
|
||||
If the test suite contains benchmarks, you can run these with the `-bench`
|
||||
flag:
|
||||
|
||||
go test -bench .
|
||||
|
||||
For more detailed info about the Go track see the [help
|
||||
page](http://help.exercism.io/getting-started-with-go.html).
|
||||
|
||||
## Source
|
||||
|
||||
Wikipedia [view source](http://en.wikipedia.org/wiki/There_Was_an_Old_Lady_Who_Swallowed_a_Fly)
|
100
go/food-chain/food_chain.go
Normal file
100
go/food-chain/food_chain.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package foodchain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TestVersion is an exercism thing
|
||||
const TestVersion = 1
|
||||
|
||||
// An Inedible is something that you probably shouldn't eat.
|
||||
// At the least, you shouldn't eat it whole/live.
|
||||
type Inedible struct {
|
||||
// What it is
|
||||
Name string
|
||||
// A quick jab about it
|
||||
FollowUp string
|
||||
}
|
||||
|
||||
// DoNotEat is a non-exhaustive list of Inedibles. It's recommended
|
||||
// that you don't eat them. Yet the old lady did.
|
||||
var DoNotEat = []Inedible{
|
||||
Inedible{
|
||||
"fly", "I don't know why she swallowed the fly. Perhaps she'll die.",
|
||||
},
|
||||
Inedible{
|
||||
"spider", "It wriggled and jiggled and tickled inside her.",
|
||||
},
|
||||
Inedible{
|
||||
"bird", "How absurd to swallow a bird!",
|
||||
},
|
||||
Inedible{
|
||||
"cat", "Imagine that, to swallow a cat!",
|
||||
},
|
||||
Inedible{
|
||||
"dog", "What a hog, to swallow a dog!",
|
||||
},
|
||||
Inedible{
|
||||
"goat", "Just opened her throat and swallowed a goat!",
|
||||
},
|
||||
Inedible{
|
||||
"cow", "I don't know how she swallowed a cow!",
|
||||
},
|
||||
Inedible{
|
||||
"horse", "She's dead, of course!",
|
||||
},
|
||||
}
|
||||
|
||||
// Verse generates the text for a specific verse
|
||||
func Verse(verseNum int) string {
|
||||
return strings.Trim(Swallow(verseNum-1, true), "\n")
|
||||
}
|
||||
|
||||
// Verses generates the text for all verses from verse1 to verse2
|
||||
func Verses(verse1, verse2 int) string {
|
||||
var ret string
|
||||
for verse1 <= verse2 {
|
||||
ret += Verse(verse1) + "\n\n"
|
||||
verse1++
|
||||
}
|
||||
return strings.Trim(ret, "\n")
|
||||
}
|
||||
|
||||
// Song generates all verses
|
||||
func Song() string {
|
||||
var ret string
|
||||
for verseNum := 1; verseNum <= len(DoNotEat); verseNum++ {
|
||||
ret += Verse(verseNum) + "\n\n"
|
||||
}
|
||||
return strings.Trim(ret, "\n")
|
||||
}
|
||||
|
||||
// Swallow generates the text for swallowing something
|
||||
func Swallow(dneIdx int, first bool) string {
|
||||
var ret string
|
||||
|
||||
if first || dneIdx == len(DoNotEat)-1 {
|
||||
ret = fmt.Sprintf(
|
||||
"I know an old lady who swallowed a %s.\n%s\n",
|
||||
DoNotEat[dneIdx].Name,
|
||||
DoNotEat[dneIdx].FollowUp,
|
||||
)
|
||||
if dneIdx == 0 || dneIdx == len(DoNotEat)-1 {
|
||||
return ret
|
||||
}
|
||||
}
|
||||
ret += fmt.Sprintf("She swallowed the %s to catch the %s",
|
||||
DoNotEat[dneIdx].Name,
|
||||
DoNotEat[dneIdx-1].Name,
|
||||
)
|
||||
if DoNotEat[dneIdx-1].Name == "spider" {
|
||||
ret += " that wriggled and jiggled and tickled inside her.\n"
|
||||
} else if DoNotEat[dneIdx-1].Name == "fly" {
|
||||
ret += ".\nI don't know why she swallowed the fly. Perhaps she'll die.\n"
|
||||
return ret
|
||||
} else {
|
||||
ret += ".\n"
|
||||
}
|
||||
return ret + Swallow(dneIdx-1, false)
|
||||
}
|
95
go/food-chain/food_chain_test.go
Normal file
95
go/food-chain/food_chain_test.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package foodchain
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const testVersion = 1
|
||||
|
||||
func TestTestVersion(t *testing.T) {
|
||||
if TestVersion != testVersion {
|
||||
t.Errorf("Found TestVersion = %v, want %v.", TestVersion, testVersion)
|
||||
}
|
||||
}
|
||||
|
||||
var ref = []string{``,
|
||||
|
||||
`I know an old lady who swallowed a fly.
|
||||
I don't know why she swallowed the fly. Perhaps she'll die.`,
|
||||
|
||||
`I know an old lady who swallowed a spider.
|
||||
It wriggled and jiggled and tickled inside her.
|
||||
She swallowed the spider to catch the fly.
|
||||
I don't know why she swallowed the fly. Perhaps she'll die.`,
|
||||
|
||||
`I know an old lady who swallowed a bird.
|
||||
How absurd to swallow a bird!
|
||||
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
|
||||
She swallowed the spider to catch the fly.
|
||||
I don't know why she swallowed the fly. Perhaps she'll die.`,
|
||||
|
||||
`I know an old lady who swallowed a cat.
|
||||
Imagine that, to swallow a cat!
|
||||
She swallowed the cat to catch the bird.
|
||||
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
|
||||
She swallowed the spider to catch the fly.
|
||||
I don't know why she swallowed the fly. Perhaps she'll die.`,
|
||||
|
||||
`I know an old lady who swallowed a dog.
|
||||
What a hog, to swallow a dog!
|
||||
She swallowed the dog to catch the cat.
|
||||
She swallowed the cat to catch the bird.
|
||||
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
|
||||
She swallowed the spider to catch the fly.
|
||||
I don't know why she swallowed the fly. Perhaps she'll die.`,
|
||||
|
||||
`I know an old lady who swallowed a goat.
|
||||
Just opened her throat and swallowed a goat!
|
||||
She swallowed the goat to catch the dog.
|
||||
She swallowed the dog to catch the cat.
|
||||
She swallowed the cat to catch the bird.
|
||||
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
|
||||
She swallowed the spider to catch the fly.
|
||||
I don't know why she swallowed the fly. Perhaps she'll die.`,
|
||||
|
||||
`I know an old lady who swallowed a cow.
|
||||
I don't know how she swallowed a cow!
|
||||
She swallowed the cow to catch the goat.
|
||||
She swallowed the goat to catch the dog.
|
||||
She swallowed the dog to catch the cat.
|
||||
She swallowed the cat to catch the bird.
|
||||
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
|
||||
She swallowed the spider to catch the fly.
|
||||
I don't know why she swallowed the fly. Perhaps she'll die.`,
|
||||
|
||||
`I know an old lady who swallowed a horse.
|
||||
She's dead, of course!`,
|
||||
}
|
||||
|
||||
func TestVerse(t *testing.T) {
|
||||
for v := 1; v <= 8; v++ {
|
||||
if ret := Verse(v); ret != ref[v] {
|
||||
t.Fatalf("Verse(%d) =\n%s\n want:\n%s\n", v, ret, ref[v])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerses(t *testing.T) {
|
||||
if ret, want := Verses(1, 2), ref[1]+"\n\n"+ref[2]; ret != want {
|
||||
t.Fatalf("Verses(1, 2) =\n%s\n want:\n%s\n", ret, want)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestSong(t *testing.T) {
|
||||
if ret, want := Song(), strings.Join(ref[1:], "\n\n"); ret != want {
|
||||
t.Fatalf("Song() =\n%s\n want:\n%s\n", ret, want)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSong(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
Song()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user