New Fetch
This commit is contained in:
64
go/pov/README.md
Normal file
64
go/pov/README.md
Normal 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
298
go/pov/pov_test.go
Normal 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
83
go/transpose/README.md
Normal 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
248
go/transpose/cases_test.go
Normal 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
32
go/transpose/transpose.go
Normal 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
|
||||
}
|
52
go/transpose/transpose_test.go
Normal file
52
go/transpose/transpose_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user