DEV Community

angeljrp
angeljrp

Posted on

Coding Odyssey: Embarking on a Matrix Adventure with Go

Hey everyone! ๐Ÿ‘‹ I just wrapped up a coding exercise that was quite the brain teaser, and it took me a solid three days to crack it. What was the challenge, you ask? Well, it was all about matrices! Buckle up as I walk you through the entire process of creating, analyzing, and tweaking matrices using the power of Go.

The Matrix Unveiled ๐Ÿงฎ

Let's start at the basics. If you're not familiar with what a matrix is, don't worryโ€”I got you covered. A matrix is like a big rectangular table filled with numbers, letters, words, or symbols, neatly arranged in rows and columns. Here's a quick visual:

    1  2  3  4
  |------------
1 | 5  8  7  9
2 | 3  1  4  6
3 | 4  6  7  4
4 | 5  6  3  2
Enter fullscreen mode Exit fullscreen mode

In this example, each number has an address: (row, column). So, if I want the number at (2, 3), I'd get 4. Easy, right?

The Matrix Code ๐Ÿš€

Now, let's dive into the nitty-gritty of the code. First things first, I had to define a custom type:

type Matrix [][]int

This custom type sets the stage for the four functions that make up the core of this coding adventure:

1. New: Creating the Matrix

The New function takes a string and transforms it into a matrix. The string must follow this specific format:

"1 2 3\n4 5 6\n7 8 9"

Each "row" is separated by \n, and the numbers within each row are the columns. Check out the code snippet:

func New(s string) (Matrix, error) {
    lines := strings.Split(s, "\n")
    matrix := make(Matrix, len(lines))

    for i, line := range lines {
        // Parse each line to create a row
        numbers := strings.Split(strings.TrimSpace(line), " ")
        row := make([]int, len(numbers))

        for j, number := range numbers {
            val, err := strconv.Atoi(number)
            if err != nil {
                return nil, err
            }
            row[j] = val
        }

        if i > 0 && len(row) != len(matrix[i-1]) {
            return nil, fmt.Errorf("uneven rows")
        }

        matrix[i] = row
    }
Enter fullscreen mode Exit fullscreen mode

This code ensures that the string is parsed correctly, and the matrix is constructed without any uneven rows.

2. Cols: Unveiling the Columns

The Cols method takes a matrix as a parameter and returns its columns in a neat [][]int format. Check out how I tackled this one:

func (m Matrix) Cols() [][]int {

    cols := make([][]int, len(m[0]))

    for i := 0; i < len(m[0]); i++ {
        cols[i] = make([]int, 0)
    }

    for i := 0; i < len(m); i++ {
        for j := 0; j < len(m[i]); j++ {
            cols[j] = append(cols[j], m[i][j])
        }
    }



    return cols
}
Enter fullscreen mode Exit fullscreen mode

This snippet cleverly transposes the matrix, turning rows into columns.

3. Rows: Fetching the Rows

The Rows method takes a matrix and returns its rows. Simple and sweet:

func (m Matrix) Rows() [][]int {
    rows := make([][]int, len(m))

    for i := 0; i < len(m); i++ {
        rows[i] = append(rows[i], m[i]...)
    }

    return rows
}
Enter fullscreen mode Exit fullscreen mode

This code snippet efficiently copies the rows from the original matrix.

4. Set: Making Changes

The Set method allows you to change a specific value in the matrix. Just provide the row, column, and the new value:

func (m Matrix) Set(row, col, val int) bool {
    if row >= len(m) || row < 0 || col >= len(m[row]) || col < 0 {
        return false
    }

    m[row][col] = val

    return m[row][col] == val
}
Enter fullscreen mode Exit fullscreen mode

This snippet ensures that you're not venturing outside the matrix boundaries and updates the value accordingly.

Here you have a snap of the code all putted down together for you to enjoy:

import (
    "fmt"
    "strconv"
    "strings"
)

type Matrix [][]int

func New(s string) (Matrix, error) {
    lines := strings.Split(s, "\n")
    matrix := make(Matrix, len(lines))

    for i, line := range lines {
        numbers := strings.Split(strings.TrimSpace(line), " ")
        row := make([]int, len(numbers))

        for j, number := range numbers {
            val, err := strconv.Atoi(number)
            if err != nil {
                return nil, err
            }
            row[j] = val
        }

        if i > 0 && len(row) != len(matrix[i-1]) {
            return nil, fmt.Errorf("uneven rows")
        }

        matrix[i] = row
    }

    return matrix, nil
}
// Cols and Rows must return the results without affecting the matrix.
func (m Matrix) Cols() [][]int {

    cols := make([][]int, len(m[0]))

    for i := 0; i < len(m[0]); i++ {
        cols[i] = make([]int, 0)
    }

    for i := 0; i < len(m); i++ {
        for j := 0; j < len(m[i]); j++ {
            cols[j] = append(cols[j], m[i][j])
        }
    }



    return cols
}

func (m Matrix) Rows() [][]int {
    rows := make([][]int, len(m))

    for i := 0; i < len(m); i++ {
        rows[i] = append(rows[i], m[i]...)
    }

    return rows
}

func (m Matrix) Set(row, col, val int) bool {
    if row >= len(m) || row < 0 || col >= len(m[row]) || col < 0 {
        return false
    }

    m[row][col] = val

    return m[row][col] == val
}
Enter fullscreen mode Exit fullscreen mode

And there you have itโ€”a journey through the matrix! ๐Ÿš€ If you're a coding enthusiast, give this exercise a shot and share your experience. Happy coding! ๐Ÿ˜Š

I want to say thanks to my great buddy Andres and my dad that helped me go trough this exercise (otherwise it would had taken me longer) thank you both a lot.

Top comments (0)