This commit is contained in:
2022-12-23 19:45:56 -08:00
commit 8792e5275a
77 changed files with 31154 additions and 0 deletions

153
solutions/day9/day9.go Normal file
View File

@@ -0,0 +1,153 @@
package day9
import (
"bufio"
"fmt"
"os"
"strconv"
)
type Point struct {
x int
y int
}
func makeSnake(length int) []*Point {
snake := []*Point{}
for i := 0; i < length; i++ {
snake = append(snake, &Point{0, 0})
}
return snake
}
func move(direction rune, point *Point) {
switch direction {
case 'U':
point.y -= 1
case 'R':
point.x += 1
case 'D':
point.y += 1
case 'L':
point.x -= 1
default:
fmt.Println("PANIC! Bad direction", string(direction))
}
}
func abs(x int) int {
if x >= 0 {
return x
} else {
return -x
}
}
func areTouching(head *Point, tail *Point) bool {
return abs(head.x-tail.x) <= 1 && abs(head.y-tail.y) <= 1
}
func updateTail(head *Point, tail *Point) {
if areTouching(head, tail) {
return
}
if head.x == tail.x {
if head.y <= tail.y-2 {
tail.y -= 1
return
}
if head.y >= tail.y+2 {
tail.y += 1
return
}
}
if head.y == tail.y {
if head.x <= tail.x-2 {
tail.x -= 1
return
}
if head.x >= tail.x+2 {
tail.x += 1
return
}
}
proposedTails := []Point{
{tail.x - 1, tail.y - 1},
{tail.x - 1, tail.y + 1},
{tail.x + 1, tail.y - 1},
{tail.x + 1, tail.y + 1}}
for _, proposed := range proposedTails {
if areTouching(head, &proposed) {
tail.x = proposed.x
tail.y = proposed.y
return
}
}
fmt.Println("PANIC, couldn't figure out next step for", *head, "and", *tail)
}
func contains(array *[]Point, point Point) bool {
for _, val := range *array {
if val == point {
return true
}
}
return false
}
func runMove(direction rune, amount int, snake []*Point, visitedPoints *[]Point) {
for i := 0; i < amount; i++ {
move(direction, snake[0])
for t := 1; t < len(snake); t++ {
updateTail(snake[t-1], snake[t])
}
lastPoint := snake[len(snake)-1]
if !contains(visitedPoints, *lastPoint) {
*visitedPoints = append(*visitedPoints, *lastPoint)
}
}
}
func Run(filename string, lengthStr string) {
file, err := os.Open(filename)
if err != nil {
fmt.Println("Error opening file:", err)
return
}
snakeLength, err := strconv.Atoi(lengthStr)
if err != nil {
fmt.Println("Error parsing snake length:", err)
return
}
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
snake := makeSnake(snakeLength)
visitedPoints := []Point{}
for scanner.Scan() {
line := scanner.Text()
amount, err := strconv.Atoi(line[2:])
if err != nil {
fmt.Println("Could not parse argument", line)
return
}
runMove(rune(line[0]), amount, snake, &visitedPoints)
}
fmt.Println("The tail visited", len(visitedPoints), "points")
file.Close()
}