This is the output of my version in Go for S = 9.
1 2 3 4 5 6 7 8 9 32 33 34 35 36 37 38 39 10 31 56 57 58 59 60 61 40 11 30 55 72 73 74 75 62 41 12 29 54 71 80 81 76 63 42 13 28 53 70 79 78 77 64 43 14 27 52 69 68 67 66 65 44 15 26 51 50 49 48 47 46 45 16 25 24 23 22 21 20 19 18 17 |
You can see why he called it the snail. Anyway, I noticed a chance to use a goroutine for this problem. In any cycle starting with [left] followed by [down] we go n steps in each direction, then n+1 steps in the [right,up] directions. In the code below, we obtain these step values from a Go channel.
A couple of other Go-like things about this code. We stash the 2D array (as a 1D array with a shape parameter) in a struct, and then attach a func to that struct to pretty print it. The details of the pprint function could doubtless be improved---I'm not too swift with formatting. The other Goish thing is to modify both the row and column indices at once, returning what we'd call in Python a tuple value from the step function.
Fun.
package main
import (
"fmt"
"os"
"strings"
)
func dist(ch chan int) {
var a int = 1
for {
ch <- a
ch <-a
a++
}
}
var m = map[string]string{"L":"D","D":"R","R":"U","U":"L"}
func step(r, c int, dir string)(rn, cn int) {
switch dir {
case "L": { c-- }
case "D": { r++ }
case "R": { c++ }
case "U": { r-- }
}
return r,c
}
type A struct { arr []int; SZ int }
func (a *A) pprint() {
d := a.SZ
for i:= 0; i < len(a.arr); i += d {
S := []string{}
for _,f := range a.arr[i:i+d] {
S = append(S,fmt.Sprintf("%2d", f))
}
fmt.Println(strings.Join(S," "))
}
}
func main() {
S := 9
if S%2 != 1 { os.Exit(1) }
N := S*S
a := A{make([]int,N), S}
ch := make(chan int)
go dist(ch)
dir := "L"
var r, c int; r = S/2 + 1; c = r
n := <- ch
for {
for i := 0; i < n; i++ {
//fmt.Println(r, c, N)
a.arr[(r-1)*S + (c-1)] = N
N--
if N == 0 { break }
r,c = step(r, c, dir)
}
n = <- ch
dir = m[dir]
if N == 0 { break }
}
a.pprint()
} |