AoC2020/day12/day12.go
Karl Spickermann d9b66adc94 Day12
2020-12-12 16:55:02 +01:00

142 lines
3.5 KiB
Go

package main
import (
"AoC2020/helper"
"fmt"
"os"
"strconv"
)
var Pointing rune
func main() {
args := os.Args[1:]
input, err := helper.GetInput(args[0])
if err != nil {
fmt.Println(err)
}
fmt.Printf("%v",input)
runPart2(input)
}
func run(input []string) {
Pointing = 'E'
position := [2]int{0,0}
for _, val := range input {
fmt.Println(val)
position = move(position,val)
fmt.Printf("Positon %v, Direction %v \n", position, string(Pointing))
}
}
func runPart2(input []string) {
positionBoat := [2]int{0,0}
positionWayPoint := [2]int{10,1}
for _, val := range input {
fmt.Println(val)
positionBoat, positionWayPoint = movePart2(positionBoat,positionWayPoint,val)
fmt.Printf("PositonBoat: %v, PositionWaypoint %v \n", positionBoat, positionWayPoint)
}
}
func move(position [2]int, command string) [2]int{
direction := rune(command[0])
distance, _ := strconv.Atoi(command[1:])
if direction == 'L' || direction == 'R' {
Pointing = turnByDegree(Pointing,direction,distance)
return position
}
if direction == 'F'{
newCommand := string(Pointing) + command[1:]
return move(position,newCommand)
}
return moveCompass(position,direction,distance)
}
func movePart2(positionBoat [2]int, positionWayPoint [2]int, command string) ([2]int, [2]int){
direction := rune(command[0])
if direction == 'F'{
distance, _ := strconv.Atoi(command[1:])
var newPositionBoat [2]int
newPositionBoat[0] = positionBoat[0] + distance * positionWayPoint[0]
newPositionBoat[1] = positionBoat[1] + distance * positionWayPoint[1]
positionBoat = newPositionBoat
}else {
newPositionWaypoint := moveWayPoint(positionWayPoint,command)
positionWayPoint = newPositionWaypoint
}
return positionBoat, positionWayPoint
}
func moveCompass(position [2]int, direction rune, distance int) [2]int {
switch direction {
case 'N':return [2]int{position[0], position[1] + distance}
case 'S':return [2]int{position[0], position[1] - distance}
case 'E':return [2]int{position[0] + distance, position[1]}
case 'W':return [2]int{position[0] - distance, position[1]}
}
return position
}
func moveWayPoint(position [2]int, command string) [2]int {
direction := rune(command[0])
distance, _ := strconv.Atoi(command[1:])
if direction == 'L' || direction == 'R' {
return turnWayPoint(position,direction,distance)
}
return moveCompass(position,direction,distance)
}
func turnWayPoint(position [2]int,turn rune, degree int) [2]int {
p0 := position[0]
p1 := position[1]
var newDs = make([]rune,2)
if p0 > 0 {
newDs[0] = turnByDegree('E', turn, degree)
}else {
newDs[0] = turnByDegree('W', turn, degree)
}
if p1 > 0 {
newDs[1] = turnByDegree('N', turn, degree)
}else {
newDs[1] = turnByDegree('S', turn, degree)
}
var newPosition [2]int
for i,val := range newDs {
switch val {
case 'N': newPosition[1] = Abs(position[i])
case 'S': newPosition[1] = -Abs(position[i])
case 'E': newPosition[0] = Abs(position[i])
case 'W': newPosition[0] = -Abs(position[i])
}
}
return newPosition
}
func turnByDegree(pointing rune, turn rune, degree int) rune {
directions := []rune{'N','E','S','W'}
move := degree / 90
if turn == 'L' {
move = -1 * move
}
for i, val := range directions {
if val == pointing {
newDirectionPointer := (i + move) % len(directions)
if newDirectionPointer < 0 {
newDirectionPointer = len(directions) + newDirectionPointer
}
return directions[newDirectionPointer]
}
}
return pointing
}
func Abs(x int) int {
if x < 0 {
return -x
}
return x
}