package main import ( "fmt" "os" "strconv" ) const ( // directions W = iota N E S ) var ( // current value cur int // current position x, y int // current direction dir int // grid bounds xmax, xmin, ymax, ymin int ) func main() { n, err := strconv.Atoi(os.Args[1]) if err != nil { os.Exit(1) } // move current position in grid and compute change direction, expand grid for cur < n { nextMove() // fmt.Println(cur, x, y) } // distance to position fmt.Println(Abs(x) + Abs(y)) } func nextMove() { if cur == 0 { dir = S } else { x1, y1 := dirMove() if outOfBound(x1, y1) { changeDir() x1, y1 = dirMove() } x, y = x1, y1 } cur++ } func dirMove() (int, int) { switch dir { case W: return x - 1, y case N: return x, y + 1 case E: return x + 1, y case S: return x, y - 1 default: return x, y } } func outOfBound(x1 int, y1 int) bool { return x1 > xmax || x1 < xmin || y1 > ymax || y1 < ymin } func changeDir() { switch dir { case W: dir = S ymin-- case N: dir = W xmin-- case E: dir = N ymax++ case S: dir = E xmax++ } } func Abs(n int) int { if n < 0 { return -n } return n }