 # oorion's solution

## to Spiral Matrix in the Go Track

Published at Oct 25 2019 · 0 comments
Instructions
Test suite
Solution

Given the size, return a square matrix of numbers in spiral order.

The matrix should be filled with natural numbers, starting from 1 in the top-left corner, increasing in an inward, clockwise spiral order, like these examples:

###### Spiral matrix of size 3
``````1 2 3
8 9 4
7 6 5
``````
###### Spiral matrix of size 4
`````` 1  2  3 4
12 13 14 5
11 16 15 6
10  9  8 7
``````

## Coding the solution

Look for a stub file having the name spiral_matrix.go and place your solution code in that file.

## Running the tests

To run the tests run the command `go test` from within the exercise directory.

If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` flags:

``````go test -v --bench . --benchmem
``````

Keep in mind that each reviewer will run benchmarks on a different machine, with different specs, so the results from these benchmark tests may vary.

## Further information

For more detailed information about the Go track, including how to get help if you're having trouble, please visit the exercism.io Go language page.

## Source

Reddit r/dailyprogrammer challenge #320 [Easy] Spiral Ascension. https://www.reddit.com/r/dailyprogrammer/comments/6i60lr/20170619_challenge_320_easy_spiral_ascension/

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### spiral_matrix_test.go

``````package spiralmatrix

import (
"reflect"
"testing"
)

var testCases = []struct {
description string
input       int
expected    [][]int
}{
{
description: "empty spiral",
input:       0,
expected:    [][]int{},
},
{
description: "trivial spiral",
input:       1,
expected: [][]int{
{1},
},
},
{
description: "spiral of size 2",
input:       2,
expected: [][]int{
{1, 2},
{4, 3},
},
},
{
description: "spiral of size 3",
input:       3,
expected: [][]int{
{1, 2, 3},
{8, 9, 4},
{7, 6, 5},
},
},
{
description: "spiral of size 4",
input:       4,
expected: [][]int{
{1, 2, 3, 4},
{12, 13, 14, 5},
{11, 16, 15, 6},
{10, 9, 8, 7},
},
},
}

func TestSpiralMatrix(t *testing.T) {
for _, testCase := range testCases {
matrix := SpiralMatrix(testCase.input)
if !reflect.DeepEqual(matrix, testCase.expected) {
t.Fatalf("FAIL: %s\n\tSpiralMatrix(%v)\nexpected: %v\ngot     : %v",
testCase.description, testCase.input, testCase.expected, matrix)
}
t.Logf("PASS: %s", testCase.description)
}
}

func BenchmarkSpiralMatrix(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, testCase := range testCases {
SpiralMatrix(testCase.input)
}
}
}``````
``````package spiralmatrix

var offsets = map[string]int{
"right": int{0, 1},
"left":  int{0, -1},
"up":    int{-1, 0},
"down":  int{1, 0},
}

var turnRight = map[string]string{
"right": "down",
"down":  "left",
"left":  "up",
"up":    "right",
}

// SpiralMatrix returns a matrix with integers that spiral clockwise
func SpiralMatrix(n int) [][]int {
matrix := make([][]int, n)

for i := range matrix {
matrix[i] = make([]int, n)
}

return generateValues(0, 0, "right", matrix)
}

func generateValues(x, y int, direction string, matrix [][]int) [][]int {
n := len(matrix)
for val := 1; val <= n*n; val++ {
matrix[x][y] = val
x, y, direction = nextPosition(x, y, matrix, direction)
}
return matrix
}

func nextPosition(x int, y int, matrix [][]int, direction string) (nextX,
nextY int,
nextDirection string) {
checkX := x + offsets[direction]
checkY := y + offsets[direction]
n := len(matrix)
if checkOutOfBounds(checkX, checkY, n) || checkHasValue(checkX, checkY, matrix) {
nextDirection = turnRight[direction]
} else {
nextDirection = direction
}

nextX = x + offsets[nextDirection]
nextY = y + offsets[nextDirection]

return
}

func checkOutOfBounds(x, y, n int) bool {
return x < 0 || x >= n || y < 0 || y >= n
}

func checkHasValue(x, y int, matrix [][]int) bool {
return matrix[x][y] != 0
}``````