Syncing Things
This commit is contained in:
parent
4beb28090e
commit
4c0197f8c6
@ -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
|
||||||
func (m *Matrix) Cols() [][]int {
|
for j := range m.vals[i] {
|
||||||
ret := [][]int{}
|
row = append(row, m.vals[i][j])
|
||||||
if len(m.vals) > 0 {
|
}
|
||||||
// for i := 0; i < len(m.vals[0]); i++ {
|
ret = append(ret, row)
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
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
|
||||||
|
45
go/saddle-points/README.md
Normal file
45
go/saddle-points/README.md
Normal 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
109
go/saddle-points/saddle.go
Normal 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
|
||||||
|
}
|
67
go/saddle-points/saddle_points_test.go
Normal file
67
go/saddle-points/saddle_points_test.go
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user