commit 35676f5313c4567468cd5834a0fe20743e5431e0
parent 9bbd3ed136e79e79f64ab5ebe8c8481641c5a8f0
Author: dwrz <dwrz@dwrz.net>
Date: Sun, 3 Mar 2019 02:36:39 +0000
Add go/twelve-days
Diffstat:
3 files changed, 196 insertions(+), 0 deletions(-)
diff --git a/go/twelve-days/README.md b/go/twelve-days/README.md
@@ -0,0 +1,53 @@
+# Twelve Days
+
+Output the lyrics to 'The Twelve Days of Christmas'.
+
+```text
+On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree.
+
+On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree.
+
+On the third day of Christmas my true love gave to me: three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
+
+On the fourth day of Christmas my true love gave to me: four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
+
+On the fifth day of Christmas my true love gave to me: five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
+
+On the sixth day of Christmas my true love gave to me: six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
+
+On the seventh day of Christmas my true love gave to me: seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
+
+On the eighth day of Christmas my true love gave to me: eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
+
+On the ninth day of Christmas my true love gave to me: nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
+
+On the tenth day of Christmas my true love gave to me: ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
+
+On the eleventh day of Christmas my true love gave to me: eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
+
+On the twelfth day of Christmas my true love gave to me: twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
+```
+
+## Running the tests
+
+To run the tests run the command `go test` from within the exercise directory.
+
+If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
+flags:
+
+ go test -v --bench . --benchmem
+
+Keep in mind that each reviewer will run benchmarks on a different machine, with
+different specs, so the results from these benchmark tests may vary.
+
+## Further information
+
+For more detailed information about the Go track, including how to get help if
+you're having trouble, please visit the exercism.io [Go language page](http://exercism.io/languages/go/resources).
+
+## Source
+
+Wikipedia [http://en.wikipedia.org/wiki/The_Twelve_Days_of_Christmas_(song)](http://en.wikipedia.org/wiki/The_Twelve_Days_of_Christmas_(song))
+
+## Submitting Incomplete Solutions
+It's possible to submit an incomplete solution so you can see how others have completed the exercise.
diff --git a/go/twelve-days/twelve-days.go b/go/twelve-days/twelve-days.go
@@ -0,0 +1,72 @@
+// Package twelve outputs the lyrics to The Twelve Days of Christmas.
+package twelve
+
+import (
+ "fmt"
+)
+
+var ordinals = [13]string{
+ "zeroth",
+ "first",
+ "second",
+ "third",
+ "fourth",
+ "fifth",
+ "sixth",
+ "seventh",
+ "eighth",
+ "ninth",
+ "tenth",
+ "eleventh",
+ "twelfth",
+}
+
+var gifts = [13]string{
+ "a null pointer",
+ "a Partridge in a Pear Tree",
+ "two Turtle Doves",
+ "three French Hens",
+ "four Calling Birds",
+ "five Gold Rings",
+ "six Geese-a-Laying",
+ "seven Swans-a-Swimming",
+ "eight Maids-a-Milking",
+ "nine Ladies Dancing",
+ "ten Lords-a-Leaping",
+ "eleven Pipers Piping",
+ "twelve Drummers Drumming",
+}
+
+func giftsForDay(day int) string {
+ switch day {
+ case 0, 1:
+ return gifts[day]
+ case 2:
+ return fmt.Sprintf(
+ "%s, and %s",
+ gifts[day],
+ gifts[day-1],
+ )
+ default:
+ return fmt.Sprintf(
+ "%s, %s",
+ gifts[day],
+ giftsForDay(day-1),
+ )
+ }
+}
+
+func Verse(day int) string {
+ return fmt.Sprintf(
+ "On the %s day of Christmas my true love gave to me: %s.",
+ ordinals[day],
+ giftsForDay(day),
+ )
+}
+
+func Song() (song string) {
+ for day := 1; day <= 12; day++ {
+ song += fmt.Sprintf("%s\n", Verse(day))
+ }
+ return
+}
diff --git a/go/twelve-days/twelve_days_test.go b/go/twelve-days/twelve_days_test.go
@@ -0,0 +1,71 @@
+package twelve
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+)
+
+type testCase struct {
+ input int
+ expected string
+}
+
+var testCases = []testCase{
+ {1, "On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree."},
+ {2, "On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree."},
+ {3, "On the third day of Christmas my true love gave to me: three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
+ {4, "On the fourth day of Christmas my true love gave to me: four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
+ {5, "On the fifth day of Christmas my true love gave to me: five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
+ {6, "On the sixth day of Christmas my true love gave to me: six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
+ {7, "On the seventh day of Christmas my true love gave to me: seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
+ {8, "On the eighth day of Christmas my true love gave to me: eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
+ {9, "On the ninth day of Christmas my true love gave to me: nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
+ {10, "On the tenth day of Christmas my true love gave to me: ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
+ {11, "On the eleventh day of Christmas my true love gave to me: eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
+ {12, "On the twelfth day of Christmas my true love gave to me: twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
+}
+
+// diff compares two multi-line strings and returns a helpful comment
+func diff(got, want string) string {
+ g := strings.Split(got, "\n")
+ w := strings.Split(want, "\n")
+ for i := 0; ; i++ {
+ switch {
+ case i < len(g) && i < len(w):
+ if g[i] == w[i] {
+ continue
+ }
+ return fmt.Sprintf("-- first difference in line %d:\n"+
+ "-- got : %q\n-- want: %q\n", i+1, g[i], w[i])
+ case i < len(g):
+ return fmt.Sprintf("-- got %d extra lines after line %d:\n"+
+ "-- first extra line: %q\n", len(g)-len(w), i, g[i])
+ case i < len(w):
+ return fmt.Sprintf("-- got %d correct lines, want %d more lines:\n"+
+ "-- want next: %q\n", i, len(w)-i, w[i])
+ default:
+ return "no differences found"
+ }
+ }
+}
+
+func TestSong(t *testing.T) {
+ var expected = ""
+ for _, test := range testCases {
+ expected += test.expected + "\n"
+ }
+ actual := Song()
+ if expected != actual {
+ t.Fatalf("Song() =\n%s\n want:\n%s\n%s", actual, expected, diff(actual, expected))
+ }
+}
+
+func TestVerse(t *testing.T) {
+ for _, test := range testCases {
+ actual := Verse(test.input)
+ if actual != test.expected {
+ t.Errorf("Twelve Days test [%d], expected [%s], actual [%s]", test.input, test.expected, actual)
+ }
+ }
+}