149 lines
2.1 KiB
Go
149 lines
2.1 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"os"
|
||
|
"strconv"
|
||
|
|
||
|
"git.annabunch.es/annabunches/adventofcode/2020/lib/fileutils"
|
||
|
)
|
||
|
|
||
|
func distance(x1, y1, x2, y2 int) int {
|
||
|
dy := y2 - y1
|
||
|
dx := x2 - x1
|
||
|
if dy < 0 {
|
||
|
dy *= -1
|
||
|
}
|
||
|
if dx < 0 {
|
||
|
dx *= -1
|
||
|
}
|
||
|
return dx + dy
|
||
|
}
|
||
|
|
||
|
func rotate(x, y int, direction byte, degrees int) (int, int) {
|
||
|
turns := degrees / 90
|
||
|
|
||
|
newX := x
|
||
|
newY := y
|
||
|
|
||
|
for i := 0; i < turns; i++ {
|
||
|
hold := newX
|
||
|
newX = newY
|
||
|
newY = hold
|
||
|
|
||
|
switch direction {
|
||
|
case 'L':
|
||
|
newX *= -1
|
||
|
case 'R':
|
||
|
newY *= -1
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return newX, newY
|
||
|
}
|
||
|
|
||
|
func step1(values []string) (int, int) {
|
||
|
facing := 90
|
||
|
x := 0
|
||
|
y := 0
|
||
|
|
||
|
for _, line := range values {
|
||
|
direction := line[0]
|
||
|
value, err := strconv.Atoi(line[1:])
|
||
|
if err != nil {
|
||
|
log.Panicf(err.Error())
|
||
|
}
|
||
|
switch direction {
|
||
|
case 'N':
|
||
|
y += value
|
||
|
case 'S':
|
||
|
y -= value
|
||
|
case 'E':
|
||
|
x += value
|
||
|
case 'W':
|
||
|
x -= value
|
||
|
case 'L':
|
||
|
facing -= value
|
||
|
case 'R':
|
||
|
facing += value
|
||
|
case 'F':
|
||
|
// the hard one
|
||
|
switch facing {
|
||
|
case 0:
|
||
|
y += value
|
||
|
case 90:
|
||
|
x += value
|
||
|
case 180:
|
||
|
y -= value
|
||
|
case 270:
|
||
|
x -= value
|
||
|
default:
|
||
|
log.Panicf("Oh no, ships can't face %d degrees!", facing)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if facing < 0 {
|
||
|
facing += 360
|
||
|
}
|
||
|
|
||
|
if facing >= 360 {
|
||
|
facing %= 360
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return x, y
|
||
|
}
|
||
|
|
||
|
func step2(values []string) (int, int) {
|
||
|
x := 0
|
||
|
y := 0
|
||
|
wayX := 10
|
||
|
wayY := 1
|
||
|
|
||
|
for _, line := range values {
|
||
|
direction := line[0]
|
||
|
value, err := strconv.Atoi(line[1:])
|
||
|
if err != nil {
|
||
|
log.Panicf(err.Error())
|
||
|
}
|
||
|
switch direction {
|
||
|
case 'N':
|
||
|
wayY += value
|
||
|
case 'S':
|
||
|
wayY -= value
|
||
|
case 'E':
|
||
|
wayX += value
|
||
|
case 'W':
|
||
|
wayX -= value
|
||
|
case 'L':
|
||
|
wayX, wayY = rotate(wayX, wayY, direction, value)
|
||
|
case 'R':
|
||
|
wayX, wayY = rotate(wayX, wayY, direction, value)
|
||
|
case 'F':
|
||
|
for i := 0; i < value; i++ {
|
||
|
x += wayX
|
||
|
y += wayY
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return x, y
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
step := os.Args[1]
|
||
|
values := fileutils.InputParserStrings(os.Args[2])
|
||
|
|
||
|
x := 0
|
||
|
y := 0
|
||
|
switch step {
|
||
|
case "1":
|
||
|
x, y = step1(values)
|
||
|
case "2":
|
||
|
x, y = step2(values)
|
||
|
}
|
||
|
|
||
|
fmt.Println(distance(x, y, 0, 0))
|
||
|
}
|