re-organise repo
This commit is contained in:
119
2022/go/day09/day09.go
Normal file
119
2022/go/day09/day09.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package day09
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"adventofcode2022/utils"
|
||||
sparsegrid "adventofcode2022/utils/sparseGrid"
|
||||
)
|
||||
|
||||
type rope struct {
|
||||
size int
|
||||
posX []int
|
||||
posY []int
|
||||
}
|
||||
|
||||
func Part1(input string) int {
|
||||
rope := newRope(2)
|
||||
grid := sparsegrid.NewGrid(false)
|
||||
grid.Set(rope.posX[rope.size-1], rope.posY[rope.size-1], true)
|
||||
for _, line := range strings.Split(input, "\n") {
|
||||
dx := 0
|
||||
dy := 0
|
||||
switch line[0] {
|
||||
case 'R':
|
||||
dx = 1
|
||||
case 'U':
|
||||
dy = -1
|
||||
case 'D':
|
||||
dy = 1
|
||||
case 'L':
|
||||
dx = -1
|
||||
}
|
||||
n := utils.MustAtoi(line[2:])
|
||||
for i := 0; i < n; i++ {
|
||||
// move head
|
||||
rope.posX[0] += dx
|
||||
rope.posY[0] += dy
|
||||
|
||||
// update tail
|
||||
rope.updateTail()
|
||||
grid.Set(rope.posX[rope.size-1], rope.posY[rope.size-1], true)
|
||||
}
|
||||
}
|
||||
return grid.Visited()
|
||||
}
|
||||
|
||||
func Part2(input string) int {
|
||||
rope := newRope(10)
|
||||
grid := sparsegrid.NewGrid(false)
|
||||
grid.Set(rope.posX[rope.size-1], rope.posY[rope.size-1], true)
|
||||
for _, line := range strings.Split(input, "\n") {
|
||||
dx := 0
|
||||
dy := 0
|
||||
switch line[0] {
|
||||
case 'R':
|
||||
dx = 1
|
||||
case 'U':
|
||||
dy = -1
|
||||
case 'D':
|
||||
dy = 1
|
||||
case 'L':
|
||||
dx = -1
|
||||
}
|
||||
n := utils.MustAtoi(line[2:])
|
||||
for i := 0; i < n; i++ {
|
||||
// move head
|
||||
rope.posX[0] += dx
|
||||
rope.posY[0] += dy
|
||||
|
||||
// update tail
|
||||
rope.updateTail()
|
||||
grid.Set(rope.posX[rope.size-1], rope.posY[rope.size-1], true)
|
||||
}
|
||||
}
|
||||
return grid.Visited()
|
||||
}
|
||||
|
||||
func newRope(size int) *rope {
|
||||
return &rope{
|
||||
size: size,
|
||||
posX: make([]int, size),
|
||||
posY: make([]int, size),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *rope) updateTail() {
|
||||
outer:
|
||||
for i := 1; i < r.size; i++ {
|
||||
diffX := utils.Abs(r.posX[i-1] - r.posX[i])
|
||||
diffY := utils.Abs(r.posY[i-1] - r.posY[i])
|
||||
if diffX <= 1 && diffY <= 1 {
|
||||
// no need to update node if it's touching
|
||||
continue
|
||||
}
|
||||
moves := [][]int{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}
|
||||
for _, move := range moves {
|
||||
t := utils.Max(
|
||||
utils.Abs(r.posX[i-1]-r.posX[i]+move[0]),
|
||||
utils.Abs(r.posY[i-1]-r.posY[i]+move[1]))
|
||||
if t == 1 {
|
||||
r.posX[i] = r.posX[i-1] + move[0]
|
||||
r.posY[i] = r.posY[i-1] + move[1]
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
moves = [][]int{{1, 1}, {-1, 1}, {1, -1}, {-1, -1}}
|
||||
for _, move := range moves {
|
||||
t := utils.Max(
|
||||
utils.Abs(r.posX[i-1]-r.posX[i]+move[0]),
|
||||
utils.Abs(r.posY[i-1]-r.posY[i]+move[1]))
|
||||
if t == 1 {
|
||||
r.posX[i] = r.posX[i-1] + move[0]
|
||||
r.posY[i] = r.posY[i-1] + move[1]
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user