126 lines
2.5 KiB
Go
126 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"AOC2022/helper"
|
|
"fmt"
|
|
"math"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type Simulation struct {
|
|
headPos [2]int
|
|
tailPos [][2]int
|
|
tailPast map[[2]int]bool
|
|
}
|
|
|
|
func main() {
|
|
args := os.Args[1:]
|
|
lines := helper.ReadTextFile(args[0])
|
|
tails := [][2]int{{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}
|
|
simulation := Simulation{[2]int{0, 0}, tails, make(map[[2]int]bool)}
|
|
for _, line := range lines {
|
|
direction, distance := getDirectionAndDistance(line)
|
|
for i := 0; i < distance; i++ {
|
|
move(&simulation.headPos, direction)
|
|
for i, _ := range tails {
|
|
simulation.moveTail(i)
|
|
}
|
|
}
|
|
}
|
|
|
|
fmt.Println(len(simulation.tailPast))
|
|
}
|
|
|
|
func getDirectionAndDistance(line string) ([2]int, int) {
|
|
splitLine := strings.Split(line, " ")
|
|
distance := helper.RemoveError(strconv.Atoi(splitLine[1]))
|
|
switch splitLine[0] {
|
|
case "U":
|
|
return [2]int{0, 1}, distance
|
|
case "D":
|
|
return [2]int{0, -1}, distance
|
|
case "R":
|
|
return [2]int{1, 0}, distance
|
|
case "L":
|
|
return [2]int{-1, 0}, distance
|
|
default:
|
|
return [2]int{0, 0}, distance
|
|
}
|
|
}
|
|
|
|
func (simulation *Simulation) moveTail(i int) {
|
|
activeTail := &simulation.tailPos[i]
|
|
if len(simulation.tailPos)-1 == i {
|
|
simulation.tailPast[*activeTail] = true
|
|
}
|
|
var nextKnot [2]int
|
|
if i == 0 {
|
|
nextKnot = simulation.headPos
|
|
} else {
|
|
nextKnot = simulation.tailPos[i-1]
|
|
}
|
|
direction := getDirectionFromTo(nextKnot[:], activeTail[:])
|
|
if getLength(direction[:]) < 2 {
|
|
return
|
|
}
|
|
if direction[0] > 0 {
|
|
activeTail[0]++
|
|
}
|
|
if direction[0] < 0 {
|
|
activeTail[0]--
|
|
}
|
|
if direction[1] > 0 {
|
|
activeTail[1]++
|
|
}
|
|
if direction[1] < 0 {
|
|
activeTail[1]--
|
|
}
|
|
if len(simulation.tailPos)-1 == i {
|
|
simulation.tailPast[*activeTail] = true
|
|
}
|
|
}
|
|
|
|
func move(object *[2]int, direction [2]int) {
|
|
object[0] += direction[0]
|
|
object[1] += direction[1]
|
|
}
|
|
|
|
func getDirectionFromTo(X, Y []int) []int {
|
|
direction := []int{}
|
|
for i, _ := range X {
|
|
direction = append(direction, X[i]-Y[i])
|
|
}
|
|
return direction
|
|
}
|
|
|
|
func getLength(X []int) float64 {
|
|
temp := float64(0)
|
|
for i, _ := range X {
|
|
temp += math.Pow(float64(X[i]), 2)
|
|
}
|
|
return math.Sqrt(temp)
|
|
}
|
|
|
|
func (simulation *Simulation) print(size int) {
|
|
for i := 0; i < size; i++ {
|
|
tempArr := ""
|
|
for j := 0; j < size; j++ {
|
|
pos := [2]int{j, size - 1 - i}
|
|
if [2]int{0, 0} == pos {
|
|
tempArr += "S"
|
|
} else if simulation.tailPast[pos] {
|
|
tempArr += "#"
|
|
} else if simulation.headPos == pos {
|
|
tempArr += "H"
|
|
} else if helper.Contains2Int(simulation.tailPos, pos) {
|
|
tempArr += "T"
|
|
} else {
|
|
tempArr += "."
|
|
}
|
|
}
|
|
fmt.Println(tempArr)
|
|
}
|
|
}
|