Syncing Things

This commit is contained in:
Brian Buller 2016-09-04 22:25:19 -05:00
parent 4beb28090e
commit 4c0197f8c6
4 changed files with 275 additions and 10 deletions

View File

@ -1,32 +1,76 @@
package matrix package matrix
import "strings" import (
"errors"
"strconv"
"strings"
)
// Matrix is a grid of ints
type Matrix struct { type Matrix struct {
vals [][]int vals [][]int
} }
// New creates a new Matrix from a string of numbers
func New(in string) (*Matrix, error) { func New(in string) (*Matrix, error) {
ret := Matrix{} ret := Matrix{}
rows := strings.Split(in, "\n") rows := strings.Split(in, "\n")
for i := range rows {
flds := strings.Fields(rows[i])
var ints []int
for j := range flds {
if v, err := strconv.Atoi(flds[j]); err != nil {
return &ret, err
} else {
ints = append(ints, v)
}
}
ret.vals = append(ret.vals, ints)
}
numInRow := -1
for i := range ret.vals {
if numInRow != -1 {
if len(ret.vals[i]) != numInRow {
return &ret, errors.New("All rows must be equal length")
}
}
numInRow = len(ret.vals[i])
}
return &ret, nil return &ret, nil
} }
// Rows returns the values of the rows in the matrix
func (m *Matrix) Rows() [][]int { func (m *Matrix) Rows() [][]int {
return m.vals var ret [][]int
for i := range m.vals {
var row []int
for j := range m.vals[i] {
row = append(row, m.vals[i][j])
} }
ret = append(ret, row)
func (m *Matrix) Cols() [][]int {
ret := [][]int{}
if len(m.vals) > 0 {
// for i := 0; i < len(m.vals[0]); i++ {
// }
} }
return ret return ret
} }
// Cols returns the values of the cols in the matrix
func (m *Matrix) Cols() [][]int {
var ret [][]int
for i := range m.vals[0] {
var row []int
for j := range m.vals {
row = append(row, m.vals[j][i])
}
ret = append(ret, row)
}
return ret
}
// Set sets the value at r,c to val
func (m *Matrix) Set(r, c int, val int) bool { func (m *Matrix) Set(r, c int, val int) bool {
if len(m.vals) < r || len(m.vals[r]) < c { if r < 0 || c < 0 {
return false
}
if len(m.vals) <= r || len(m.vals[r]) <= c {
return false return false
} }
m.vals[r][c] = val m.vals[r][c] = val

View File

@ -0,0 +1,45 @@
# Saddle Points
Write a program that detects saddle points in a matrix.
So say you have a matrix like so:
```plain
0 1 2
|---------
0 | 9 8 7
1 | 5 3 2 <--- saddle point at (1,0)
2 | 6 6 7
```
It has a saddle point at (1, 0).
It's called a "saddle point" because it is greater than or equal to
every element in its row and the less than or equal to every element in
its column.
A matrix may have zero or more saddle points.
Your code should be able to provide the (possibly empty) list of all the
saddle points for any given matrix.
Note that you may find other definitions of matrix saddle points online,
but the tests for this exercise follow the above unambiguous definition.
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://exercism.io/languages/go).
## Source
J Dalbey's Programming Practice problems [http://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html](http://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html)
## Submitting Incomplete Problems
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

109
go/saddle-points/saddle.go Normal file
View File

@ -0,0 +1,109 @@
package matrix
import (
"errors"
"fmt"
"strconv"
"strings"
)
// Matrix is a grid of ints
type Matrix struct {
vals [][]int
}
type Pair [2]int
// New creates a new Matrix from a string of numbers
func New(in string) (*Matrix, error) {
ret := Matrix{}
rows := strings.Split(in, "\n")
for i := range rows {
flds := strings.Fields(rows[i])
var ints []int
for j := range flds {
if v, err := strconv.Atoi(flds[j]); err != nil {
return &ret, err
} else {
ints = append(ints, v)
}
}
ret.vals = append(ret.vals, ints)
}
numInRow := -1
for i := range ret.vals {
if numInRow != -1 {
if len(ret.vals[i]) != numInRow {
return &ret, errors.New("All rows must be equal length")
}
}
numInRow = len(ret.vals[i])
}
return &ret, nil
}
func (m *Matrix) Saddle() []Pair {
var ret []Pair
// We're going to get a list of coords for row highs
// then compare that to a list of coords for col lows
var testRows []Pair
for i := range m.vals {
testRows = append(testRows, Pair{i, m.findRowHigh(i)})
}
fmt.Println(testRows)
return ret
for j := range m.vals[0] {
v := Pair{m.findColLow(j), j}
// If this pair is in testRows, it's a saddle point
for i := range testRows {
if v[0] == testRows[i][0] && v[1] == testRows[i][1] {
ret = append(ret, v)
}
}
}
return ret
}
// Cols returns the values of the cols in the matrix
func (m *Matrix) Cols() [][]int {
var ret [][]int
for i := range m.vals[0] {
var row []int
for j := range m.vals {
row = append(row, m.vals[j][i])
}
ret = append(ret, row)
}
return ret
}
// findColLow finds the lowest value in a column
func (m *Matrix) findColLow(c int) int {
cols := m.Cols()
var idx int
val := -1
if c >= 0 && c < len(cols) {
for i := range cols[c] {
if cols[c][i] < val || val == -1 {
val = cols[c][i]
idx = i
}
}
}
return idx
}
// findColLow finds the lowest value in a column
func (m *Matrix) findRowHigh(r int) int {
var idx int
val := -1
if r >= 0 && r < len(m.vals) {
for i := range m.vals[r] {
if m.vals[r][i] < val || val == -1 {
val = m.vals[r][i]
idx = i
}
}
}
return idx
}

View File

@ -0,0 +1,67 @@
// Short cut! Have you already done the matrix exercise?
// If it seems helpful, copy your code from the matrix exercise
// to this directory so you have access to it. You can leave it as matrix.go
// and start a new file saddle_points.go with additional code that completes
// this exercise. Submit only saddle_points.go for this exercise.
package matrix
import "testing"
var tests = []struct {
m string
sp []Pair
}{
{"2 1\n1 2", nil},
{"1 2\n3 4", []Pair{{0, 1}}},
{"18 3 39 19 91\n38 10 8 77 320\n3 4 8 6 7", []Pair{{2, 2}}},
{"4 5 4\n3 5 5\n1 5 4", []Pair{{0, 1}, {1, 1}, {2, 1}}},
}
func TestSaddle(t *testing.T) {
for _, test := range tests {
m, err := New(test.m)
if err != nil {
t.Fatalf("TestSaddle needs working New. "+
"New(%s) returned %s. Error not expected.",
test.m, err)
}
if sp := m.Saddle(); !eq(sp, test.sp) {
t.Fatalf("%v.Saddle() = %v, want %v", m, sp, test.sp)
}
}
}
func eq(got, exp []Pair) bool {
if len(got) != len(exp) {
return false
}
exp:
for _, e := range exp {
for _, g := range got {
if g == e {
continue exp
}
}
return false
}
return true
}
func BenchmarkSaddle(b *testing.B) {
ms := make([]*Matrix, len(tests))
var err error
for i, test := range tests {
if ms[i], err = New(test.m); err != nil {
b.Fatalf("BenchmarkSaddle needs working New. "+
"New(%s) returned %s. Error not expected.",
test.m, err)
}
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, m := range ms {
m.Saddle()
}
}
}