// Package matrix is the Matrix exercise on exercism.org.
package matrix
import (
"fmt"
"strconv"
"strings"
)
// Matrix is a 2 dimensional matrix of ints.
type Matrix [][]int
// New creates a Matrix parsing input. Returns error when unable to parse input.
func New(input string) (*Matrix, error) {
lines := strings.Split(input, "\n")
m := make(Matrix, len(lines))
for i, l := range lines {
row := strings.Split(strings.TrimLeft(l, " "), " ")
if i > 0 && len(row) != len(m[0]) {
return nil, fmt.Errorf("this is not a matrix")
}
// initialize items in the Matrix
m[i] = make([]int, len(row))
var err error
for j, r := range row {
m[i][j], err = strconv.Atoi(r)
if err != nil {
return nil, fmt.Errorf("parsing error")
}
}
}
return &m, nil
}
func (m Matrix) Rows() [][]int {
ret := make(Matrix, len(m))
for i, r := range m {
ret[i] = make([]int, len(r))
copy(ret[i], r)
}
return ret
}
func (m Matrix) Cols() [][]int {
var ret Matrix
for i := range m {
if i == 0 {
// Have to initialize the new matrix, as it do not have to be symmetric
// We create the new layout here
ret = make(Matrix, len(m[i])) // col lenth -> number of rows
for k := range ret {
ret[k] = make([]int, len(m)) // num of rows -> col length
}
}
for j := range m[i] {
ret[j][i] = m[i][j]
}
}
return ret
}
func (m Matrix) Set(r, c, v int) bool {
if r < 0 || r >= len(m) {
return false
}
if c < 0 || c >= len(m[r]) {
return false
}
m[r][c] = v
return true
}