New Fetch

This commit is contained in:
2017-08-12 09:01:07 -05:00
parent ba838ca4fb
commit a9630f6ee8
58 changed files with 2530 additions and 0 deletions

64
go/pov/README.md Normal file
View File

@@ -0,0 +1,64 @@
# Pov
Reparent a graph on a selected node.
# Tree Reparenting
This exercise is all about re-orientating a graph to see things from a different
point of view. For example family trees are usually presented from the
ancestor's perspective:
```
+------0------+
| | |
+-1-+ +-2-+ +-3-+
| | | | | |
4 5 6 7 8 9
```
But the same information can be presented from the perspective of any other node
in the graph, by pulling it up to the root and dragging its relationships along
with it. So the same graph from 6's perspective would look like:
```
6
|
+-----2-----+
| |
7 +-----0-----+
| |
+-1-+ +-3-+
| | | |
4 5 8 9
```
This lets us more simply describe the paths between two nodes. So for example
the path from 6-9 (which in the first graph goes up to the root and then down to
a different leaf node) can be seen to follow the path 6-2-0-3-9
This exercise involves taking an input graph and re-orientating it from the point
of view of one of the nodes.
## 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`
flag:
go test -bench .
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/about).
## Source
Adaptation of exercise from 4clojure [https://www.4clojure.com/](https://www.4clojure.com/)
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

298
go/pov/pov_test.go Normal file
View File

@@ -0,0 +1,298 @@
package pov
import (
"reflect"
"sort"
"testing"
)
const targetTestVersion = 2
// POV / reparent / change root of a tree
//
// API:
// type Graph
// func New() *Graph
// func (*Graph) AddNode(nodeLabel string)
// func (*Graph) AddArc(from, to string)
// func (*Graph) ArcList() []string
// func (*Graph) ChangeRoot(oldRoot, newRoot string) *Graph
//
// The type name is Graph because you'll probably be implementing a general
// directed graph representation, although the test program will only use
// it to create a tree. The term "arc" is used here to mean a directed edge.
//
// The test program will create a graph with New, then use AddNode to add
// leaf nodes. After that it will use AddArc to construct the rest of the tree
// from the bottom up. That is, the `to` argument will aways specify a node
// that has already been added.
//
// ArcList is a dump method to let the test program see your graph. It must
// return a list of all arcs in the graph. Format each arc as a single string
// like "from -> to". The test program can then easily sort the list and
// compare it to an expected result. You do not need to bother with sorting
// the list yourself.
//
// All this graph construction and dumping must be working before you start
// on the interesting part of the exercise, so it is tested separately as
// a first test.
//
// API function ChangeRoot does the interesting part of the exercise.
// OldRoot is passed (as a convenience) and you must return a graph with
// newRoot as the root. You can modify the original graph in place and
// return it or create a new graph and return that. If you return a new
// graph you are free to consume or destroy the original graph. Of course
// it's nice to leave it unmodified.
type arc struct{ fr, to string }
type testCase struct {
description string
leaves []string
arcPairs []arc
root string
arcStrings []string
reRooted []string
}
var testCases = []testCase{
{
description: "singleton",
leaves: []string{"x"},
arcPairs: nil,
root: "x",
arcStrings: nil,
reRooted: nil,
},
{
description: "simple tree",
leaves: []string{"sibling", "x"},
arcPairs: []arc{
{"parent", "sibling"},
{"parent", "x"},
},
root: "parent",
arcStrings: []string{
"parent -> sibling",
"parent -> x",
},
reRooted: []string{
"parent -> sibling",
"x -> parent",
},
},
{
description: "large flat",
leaves: []string{"sib-a", "sib-b", "x", "sib-c", "sib-d"},
arcPairs: []arc{
{"parent", "sib-a"},
{"parent", "sib-b"},
{"parent", "x"},
{"parent", "sib-c"},
{"parent", "sib-d"},
},
root: "parent",
arcStrings: []string{
"parent -> sib-a",
"parent -> sib-b",
"parent -> sib-c",
"parent -> sib-d",
"parent -> x",
},
reRooted: []string{
"parent -> sib-a",
"parent -> sib-b",
"parent -> sib-c",
"parent -> sib-d",
"x -> parent",
},
},
{
description: "deeply nested",
leaves: []string{"x"},
arcPairs: []arc{
{"level-4", "x"},
{"level-3", "level-4"},
{"level-2", "level-3"},
{"level-1", "level-2"},
{"level-0", "level-1"},
},
root: "level-0",
arcStrings: []string{
"level-0 -> level-1",
"level-1 -> level-2",
"level-2 -> level-3",
"level-3 -> level-4",
"level-4 -> x",
},
reRooted: []string{
"level-1 -> level-0",
"level-2 -> level-1",
"level-3 -> level-2",
"level-4 -> level-3",
"x -> level-4",
},
},
{
description: "cousins",
leaves: []string{"sib-1", "x", "sib-2", "cousin-1", "cousin-2"},
arcPairs: []arc{
{"parent", "sib-1"},
{"parent", "x"},
{"parent", "sib-2"},
{"aunt", "cousin-1"},
{"aunt", "cousin-2"},
{"grand-parent", "parent"},
{"grand-parent", "aunt"},
},
root: "grand-parent",
arcStrings: []string{
"aunt -> cousin-1",
"aunt -> cousin-2",
"grand-parent -> aunt",
"grand-parent -> parent",
"parent -> sib-1",
"parent -> sib-2",
"parent -> x",
},
reRooted: []string{
"aunt -> cousin-1",
"aunt -> cousin-2",
"grand-parent -> aunt",
"parent -> grand-parent",
"parent -> sib-1",
"parent -> sib-2",
"x -> parent",
},
},
{
description: "target with children",
leaves: []string{"child-1", "child-2", "nephew", "niece",
"2nd-cousin-1", "2nd-cousin-2", "2nd-cousin-3", "2nd-cousin-4"},
arcPairs: []arc{
{"x", "child-1"},
{"x", "child-2"},
{"sibling", "nephew"},
{"sibling", "niece"},
{"cousin-1", "2nd-cousin-1"},
{"cousin-1", "2nd-cousin-2"},
{"cousin-2", "2nd-cousin-3"},
{"cousin-2", "2nd-cousin-4"},
{"parent", "x"},
{"parent", "sibling"},
{"aunt", "cousin-1"},
{"aunt", "cousin-2"},
{"grand-parent", "parent"},
{"grand-parent", "aunt"},
},
root: "grand-parent",
arcStrings: []string{
"aunt -> cousin-1",
"aunt -> cousin-2",
"cousin-1 -> 2nd-cousin-1",
"cousin-1 -> 2nd-cousin-2",
"cousin-2 -> 2nd-cousin-3",
"cousin-2 -> 2nd-cousin-4",
"grand-parent -> aunt",
"grand-parent -> parent",
"parent -> sibling",
"parent -> x",
"sibling -> nephew",
"sibling -> niece",
"x -> child-1",
"x -> child-2",
},
reRooted: []string{
"aunt -> cousin-1",
"aunt -> cousin-2",
"cousin-1 -> 2nd-cousin-1",
"cousin-1 -> 2nd-cousin-2",
"cousin-2 -> 2nd-cousin-3",
"cousin-2 -> 2nd-cousin-4",
"grand-parent -> aunt",
"parent -> grand-parent",
"parent -> sibling",
"sibling -> nephew",
"sibling -> niece",
"x -> child-1",
"x -> child-2",
"x -> parent",
},
},
}
func (tc testCase) graph() *Graph {
g := New()
for _, l := range tc.leaves {
g.AddNode(l)
}
for _, a := range tc.arcPairs {
g.AddArc(a.fr, a.to)
}
return g
}
func (tc testCase) testResult(got, want []string, msg string, t *testing.T) {
if len(got)+len(want) == 0 {
return
}
gs := append([]string{}, got...)
sort.Strings(gs)
if reflect.DeepEqual(gs, want) {
return
}
// test has failed
t.Log(tc.description, "test case")
t.Log(msg)
t.Logf("got %d arcs:", len(got))
for _, s := range got {
t.Log(" ", s)
}
t.Logf("that result sorted:")
for _, s := range gs {
t.Log(" ", s)
}
t.Logf("want %d arcs:", len(want))
for _, s := range want {
t.Log(" ", s)
}
t.FailNow()
}
func TestTestVersion(t *testing.T) {
if testVersion != targetTestVersion {
t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
}
}
func TestConstruction(t *testing.T) {
for _, tc := range testCases {
got := tc.graph().ArcList()
want := tc.arcStrings
tc.testResult(got, want, "incorrect graph construction", t)
}
}
func TestChangeRoot(t *testing.T) {
for _, tc := range testCases {
got := tc.graph().ChangeRoot(tc.root, "x").ArcList()
want := tc.reRooted
tc.testResult(got, want, "incorrect root change", t)
}
}
func BenchmarkConstructOnlyNoChange(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, tc := range testCases {
tc.graph()
}
}
}
func BenchmarkConstructAndChangeRoot(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, tc := range testCases {
tc.graph().ChangeRoot(tc.root, "x")
}
}
}

83
go/transpose/README.md Normal file
View File

@@ -0,0 +1,83 @@
# Transpose
Given an input text output it transposed.
Roughly explained, the transpose of a matrix:
```
ABC
DEF
```
is given by:
```
AD
BE
CF
```
Rows become columns and columns become rows. See <https://en.wikipedia.org/wiki/Transpose>.
If the input has rows of different lengths, this is to be solved as follows:
- Pad to the left with spaces.
- Don't pad to the right.
Therefore, transposing this matrix:
```
ABC
DE
```
results in:
```
AD
BE
C
```
And transposing:
```
AB
DEF
```
results in:
```
AD
BE
F
```
In general, all characters from the input should also be present in the transposed output.
That means that if a column in the input text contains only spaces on its bottom-most row(s),
the corresponding output row should contain the spaces in its right-most column(s).
## 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`
flag:
go test -bench .
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/about).
## Source
Reddit r/dailyprogrammer challenge #270 [Easy]. [https://www.reddit.com/r/dailyprogrammer/comments/4msu2x/challenge_270_easy_transpose_the_input_text](https://www.reddit.com/r/dailyprogrammer/comments/4msu2x/challenge_270_easy_transpose_the_input_text)
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

248
go/transpose/cases_test.go Normal file
View File

@@ -0,0 +1,248 @@
package transpose
// Source: exercism/x-common
// Commit: 6dba022 transpose: Fix canonical-data.json formatting
// x-common version: 1.0.0
var testCases = []struct {
description string
input []string
expected []string
}{
{
"empty string",
[]string{},
[]string{},
},
{
"two characters in a row",
[]string{
"A1",
},
[]string{
"A",
"1",
},
},
{
"two characters in a column",
[]string{
"A",
"1",
},
[]string{
"A1",
},
},
{
"simple",
[]string{
"ABC",
"123",
},
[]string{
"A1",
"B2",
"C3",
},
},
{
"single line",
[]string{
"Single line.",
},
[]string{
"S",
"i",
"n",
"g",
"l",
"e",
" ",
"l",
"i",
"n",
"e",
".",
},
},
{
"first line longer than second line",
[]string{
"The fourth line.",
"The fifth line.",
},
[]string{
"TT",
"hh",
"ee",
" ",
"ff",
"oi",
"uf",
"rt",
"th",
"h ",
" l",
"li",
"in",
"ne",
"e.",
".",
},
},
{
"second line longer than first line",
[]string{
"The first line.",
"The second line.",
},
[]string{
"TT",
"hh",
"ee",
" ",
"fs",
"ie",
"rc",
"so",
"tn",
" d",
"l ",
"il",
"ni",
"en",
".e",
" .",
},
},
{
"square",
[]string{
"HEART",
"EMBER",
"ABUSE",
"RESIN",
"TREND",
},
[]string{
"HEART",
"EMBER",
"ABUSE",
"RESIN",
"TREND",
},
},
{
"rectangle",
[]string{
"FRACTURE",
"OUTLINED",
"BLOOMING",
"SEPTETTE",
},
[]string{
"FOBS",
"RULE",
"ATOP",
"CLOT",
"TIME",
"UNIT",
"RENT",
"EDGE",
},
},
{
"triangle",
[]string{
"T",
"EE",
"AAA",
"SSSS",
"EEEEE",
"RRRRRR",
},
[]string{
"TEASER",
" EASER",
" ASER",
" SER",
" ER",
" R",
},
},
{
"many lines",
[]string{
"Chor. Two households, both alike in dignity,",
"In fair Verona, where we lay our scene,",
"From ancient grudge break to new mutiny,",
"Where civil blood makes civil hands unclean.",
"From forth the fatal loins of these two foes",
"A pair of star-cross'd lovers take their life;",
"Whose misadventur'd piteous overthrows",
"Doth with their death bury their parents' strife.",
"The fearful passage of their death-mark'd love,",
"And the continuance of their parents' rage,",
"Which, but their children's end, naught could remove,",
"Is now the two hours' traffic of our stage;",
"The which if you with patient ears attend,",
"What here shall miss, our toil shall strive to mend.",
},
[]string{
"CIFWFAWDTAWITW",
"hnrhr hohnhshh",
"o oeopotedi ea",
"rfmrmash cn t",
".a e ie fthow ",
" ia fr weh,whh",
"Trnco miae ie",
"w ciroitr btcr",
"oVivtfshfcuhhe",
" eeih a uote ",
"hrnl sdtln is",
"oot ttvh tttfh",
"un bhaeepihw a",
"saglernianeoyl",
"e,ro -trsui ol",
"h uofcu sarhu ",
"owddarrdan o m",
"lhg to'egccuwi",
"deemasdaeehris",
"sr als t ists",
",ebk 'phool'h,",
" reldi ffd ",
"bweso tb rtpo",
"oea ileutterau",
"t kcnoorhhnatr",
"hl isvuyee'fi ",
" atv es iisfet",
"ayoior trr ino",
"l lfsoh ecti",
"ion vedpn l",
"kuehtteieadoe ",
"erwaharrar,fas",
" nekt te rh",
"ismdsehphnnosa",
"ncuse ra-tau l",
" et tormsural",
"dniuthwea'g t ",
"iennwesnr hsts",
"g,ycoi tkrttet",
"n ,l r s'a anr",
"i ef 'dgcgdi",
"t aol eoe,v",
"y nei sl,u; e",
", .sf to l ",
" e rv d t",
" ; ie o",
" f, r ",
" e e m",
" . m e",
" o n",
" v d",
" e .",
" ,",
},
},
}

32
go/transpose/transpose.go Normal file
View File

@@ -0,0 +1,32 @@
package transpose
import (
"strings"
)
const testVersion = 1
func Transpose(inp []string) []string {
// find the longest length string in the slice
lng := 0
for i := range inp {
if len(inp[i]) > lng {
lng = len(inp[i])
}
}
ret := make([]string, lng, lng)
for i := range inp {
for j := 0; j < lng; j++ {
if len(inp[i]) > j {
ret[j] = ret[j] + string(inp[i][j])
} else {
ret[j] = ret[j] + " "
}
}
}
if len(ret) > 0 {
// Trim the spaces off of the end of the last line
ret[len(ret)-1] = strings.TrimRight(ret[len(ret)-1], " ")
}
return ret
}

View File

@@ -0,0 +1,52 @@
package transpose
import (
"reflect"
"testing"
)
const targetTestVersion = 1
func TestTestVersion(t *testing.T) {
if testVersion != targetTestVersion {
t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
}
}
func TestTranspose(t *testing.T) {
for _, test := range testCases {
actual := Transpose(test.input)
if !reflect.DeepEqual(actual, test.expected) {
// check for zero length slices
if len(actual) == 0 || len(test.expected) == 0 {
t.Fatalf("\n\tTranspose(%q): %s\n\n\tExpected: %q\n\tGot: %q",
test.input, test.description, test.expected, actual)
}
// let's make the error more specific and find the row it's on
min := min(len(test.expected), len(actual))
for i := 0; i < min; i++ {
if test.expected[i] != actual[i] {
t.Fatalf("\n\tTranspose(%q): %s\n\n\tExpected: %q\n\tGot: %q\n\n\tRow %d Expected: %q Got: %q",
test.input, test.description, test.expected, actual, i, test.expected[i], actual[i])
}
}
}
}
}
// helper function
// https://stackoverflow.com/questions/27516387/what-is-the-correct-way-to-find-the-min-between-two-integers-in-go
func min(a, b int) int {
if a < b {
return a
}
return b
}
func BenchmarkTranspose(b *testing.B) {
for _, test := range testCases {
for i := 0; i < b.N; i++ {
Transpose(test.input)
}
}
}