95 lines
1.1 KiB
Go
95 lines
1.1 KiB
Go
|
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
|
||
|
}
|