snail
, running it with a number argument (for the square size) should look like this:$ ./snail 5 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9
So, the solution is straightforward: do alternating row and column sweeps, from the outside going inwards, while incrementing the value to be written into a matrix element.
But first, we have to be able to get the input size of the matrix. For that we'll use the
flag
and strconv
packages. For the print out, we'll use the fmt
package. Here's what I came up with.package main import ( "fmt" "flag" "strconv" ) func main() { // Determine the matrix size, n. var n int = 1 flag.Parse() if len(flag.Args()) > 0 { n, _ = strconv.Atoi(flag.Arg(0)) } if n < 1 { n = 1 } // No need to be complicated for n=1 if n == 1 { fmt.Println(n) return } // Create the matrix values := make([][]int, n) for i := 0; i < n; i++ { values[i] = make([]int, n) } // Fill the matrix with values avalue := 0 for ifill := 0; ifill < n; ifill++ { fstart := ifill fend := n-ifill // upper x forward sweep for ixf := fstart; ixf < fend-1; ixf++ { avalue++ values[fstart][ixf] = avalue } // right y forward sweep for iyf := fstart; iyf < fend-1; iyf++ { avalue++ values[iyf][fend-1] = avalue } // lower x backward sweep for ixb := fend-1; ixb > fstart; ixb-- { avalue++ values[fend-1][ixb] = avalue } // left y backward sweep for iyb := fend-1; iyb > fstart; iyb-- { avalue++ values[iyb][fstart] = avalue } } // Take care of the last value for odd n if avalue < n*n { avalue++ values[n/2][n/2] = avalue } // Ensure the same spacing for each element places := int(n*n/10) entry_width := 1 for places > 0 { entry_width++ places /= 10 } format := fmt.Sprintf("%%%dd ", entry_width) // Print out the snail for i := 0; i < n; i++ { for j := 0; j < n ; j++ { fmt.Printf(format, values[i][j]) } fmt.Println("") } }
What about you? Have you tried solving this problem in golang? How would you do it better?