2022 Day 9 Complete!
This commit is contained in:
166
2022/day09/main.go
Normal file
166
2022/day09/main.go
Normal file
@@ -0,0 +1,166 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
var sleepTime = (time.Second / 5)
|
||||
|
||||
var minx, miny, maxx, maxy int
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
|
||||
watch := len(os.Args) > 1 && strings.HasPrefix(os.Args[1], "-w")
|
||||
if watch {
|
||||
if strings.Contains(os.Args[1], "=") {
|
||||
pts := strings.Split(os.Args[1], "=")
|
||||
sleepTime = (time.Second / time.Duration(h.Atoi(pts[1])))
|
||||
}
|
||||
}
|
||||
simulate(inp, 10, watch)
|
||||
}
|
||||
|
||||
func buildInstructions(inp []string) []byte {
|
||||
var inst []byte
|
||||
for i := range inp {
|
||||
dir, count := inp[i][0], h.Atoi(inp[i][2:])
|
||||
for j := 0; j < count; j++ {
|
||||
inst = append(inst, dir)
|
||||
}
|
||||
}
|
||||
return inst
|
||||
}
|
||||
|
||||
func simulate(inp []string, knotCount int, watch bool) {
|
||||
if watch {
|
||||
fmt.Print(h.CLEAR_SCREEN)
|
||||
}
|
||||
visited := make(map[h.Coordinate]bool)
|
||||
inst := buildInstructions(inp)
|
||||
var knots []h.Coordinate
|
||||
for i := 0; i < knotCount; i++ {
|
||||
knots = append(knots, h.Coordinate{X: 0, Y: 0})
|
||||
}
|
||||
if watch {
|
||||
fmt.Println("# Part 1")
|
||||
printVisits(visited, knots)
|
||||
}
|
||||
for i, dir := range inst {
|
||||
moveHead(dir, knots)
|
||||
visited[knots[len(knots)-1]] = true
|
||||
if watch {
|
||||
time.Sleep(sleepTime)
|
||||
fmt.Print(h.CLEAR_SCREEN)
|
||||
fmt.Printf("# Part 1 (%d/%d)\n", i, len(inst))
|
||||
printVisits(visited, knots)
|
||||
}
|
||||
}
|
||||
if watch {
|
||||
time.Sleep(sleepTime)
|
||||
fmt.Print(h.CLEAR_SCREEN)
|
||||
}
|
||||
fmt.Println("# Part 1")
|
||||
if watch {
|
||||
printVisits(visited, knots)
|
||||
}
|
||||
fmt.Printf("Tail visited %d positions\n", len(visited))
|
||||
}
|
||||
|
||||
func moveHead(dir byte, knots []h.Coordinate) {
|
||||
prevKnots := make([]h.Coordinate, len(knots))
|
||||
copy(prevKnots, knots)
|
||||
switch dir {
|
||||
case 'U':
|
||||
knots[0] = knots[0].North()
|
||||
case 'R':
|
||||
knots[0] = knots[0].East()
|
||||
case 'D':
|
||||
knots[0] = knots[0].South()
|
||||
case 'L':
|
||||
knots[0] = knots[0].West()
|
||||
}
|
||||
if knots[0].X < minx {
|
||||
minx = knots[0].X
|
||||
}
|
||||
if knots[0].X > maxx {
|
||||
maxx = knots[0].X
|
||||
}
|
||||
if knots[0].Y < miny {
|
||||
miny = knots[0].Y
|
||||
}
|
||||
if knots[0].Y > maxy {
|
||||
maxy = knots[0].Y
|
||||
}
|
||||
for i := 1; i < len(knots); i++ {
|
||||
// Go through all knots and check if any need to move
|
||||
if !knots[i].Equals(knots[i-1]) && !knots[i].Adjacent(knots[i-1]) {
|
||||
if knots[i].X == knots[i-1].X {
|
||||
// Same column
|
||||
if knots[i].Y < knots[i-1].Y {
|
||||
knots[i].Y++
|
||||
} else {
|
||||
knots[i].Y--
|
||||
}
|
||||
} else if knots[i].Y == knots[i-1].Y {
|
||||
// Save row
|
||||
if knots[i].X < knots[i-1].X {
|
||||
knots[i].X++
|
||||
} else {
|
||||
knots[i].X--
|
||||
}
|
||||
} else {
|
||||
// Not in the same row or column
|
||||
if knots[i].X < knots[i-1].X {
|
||||
knots[i].X++
|
||||
} else {
|
||||
knots[i].X--
|
||||
}
|
||||
if knots[i].Y < knots[i-1].Y {
|
||||
knots[i].Y++
|
||||
} else {
|
||||
knots[i].Y--
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If one knot didn't need to move, none behind it will
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func printVisits(m map[h.Coordinate]bool, knots []h.Coordinate) {
|
||||
for y := miny; y <= maxy; y++ {
|
||||
for x := minx; x <= maxx; x++ {
|
||||
var isKnot bool
|
||||
for i := range knots {
|
||||
if knots[i].X == x && knots[i].Y == y {
|
||||
isKnot = true
|
||||
var bt byte
|
||||
if i == 0 {
|
||||
bt = 'H'
|
||||
} else {
|
||||
bt = '0' + byte(i)
|
||||
}
|
||||
fmt.Print(string(bt))
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isKnot {
|
||||
if v, ok := m[h.Coordinate{X: x, Y: y}]; ok && v {
|
||||
fmt.Print("#")
|
||||
} else {
|
||||
fmt.Print(".")
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Printf("Bridge: %s\n", knots)
|
||||
fmt.Println()
|
||||
}
|
||||
Reference in New Issue
Block a user