110 lines
2.1 KiB
Go
110 lines
2.1 KiB
Go
|
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
|
||
|
}
|