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 }