Skip to content

Commit 6685d2b

Browse files
committed
2022 day 9
1 parent 3cf4207 commit 6685d2b

File tree

3 files changed

+2174
-0
lines changed

3 files changed

+2174
-0
lines changed

2022/go/day9/day9.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"math"
6+
"os"
7+
"strings"
8+
)
9+
10+
func main() {
11+
input, _ := os.ReadFile("../../input/day9.txt")
12+
moves := parseMoves(string(input))
13+
head := tieKnots(10)
14+
head = runMoves(head, moves)
15+
fmt.Printf("part1 : %d\n", len(head.getNth(1).visited))
16+
fmt.Printf("part2 : %d\n", len(head.getNth(9).visited))
17+
}
18+
19+
func tieKnots(count int) *knot {
20+
knot := newKnot()
21+
prev := knot
22+
for i := 1; i < count; i++ {
23+
prev.tail = newKnot()
24+
prev = prev.tail
25+
}
26+
return knot
27+
}
28+
29+
func runMoves(knot *knot, moves []move) *knot {
30+
for _, m := range moves {
31+
for s := byte(0); s < m.steps; s++ {
32+
knot.move(dirs[m.dir])
33+
}
34+
}
35+
return knot
36+
}
37+
38+
type pos struct {
39+
x, y int
40+
}
41+
42+
type knot struct {
43+
pos pos
44+
visited map[pos]bool
45+
tail *knot
46+
}
47+
48+
type move struct {
49+
dir, steps byte
50+
}
51+
52+
func (k *knot) getNth(count int) *knot {
53+
if count == 0 {
54+
return k
55+
}
56+
return k.tail.getNth(count - 1)
57+
}
58+
59+
func (k *knot) move(v pos) {
60+
k.pos = k.pos.move(v)
61+
k.visited[k.pos] = true
62+
if k.tail != nil {
63+
k.tail.follow(k)
64+
}
65+
}
66+
67+
func (p pos) move(v pos) pos {
68+
return pos{p.x + v.x, p.y + v.y}
69+
}
70+
71+
func (tail *knot) follow(head *knot) {
72+
if tail.pos.touching(head.pos) {
73+
return
74+
}
75+
dx := (head.pos.x-tail.pos.x)/2 + (head.pos.x-tail.pos.x)%2
76+
dy := (head.pos.y-tail.pos.y)/2 + (head.pos.y-tail.pos.y)%2
77+
tail.move(pos{dx, dy})
78+
}
79+
80+
func (k1 pos) touching(k2 pos) bool {
81+
return math.Abs(float64(k1.x)-float64(k2.x)) < 1.5 && math.Abs(float64(k1.y)-float64(k2.y)) < 1.5
82+
}
83+
84+
func parseMoves(input string) (moves []move) {
85+
lines := strings.Split(input, "\n")
86+
for _, line := range lines {
87+
var m move
88+
fmt.Sscanf(line, "%c %d", &m.dir, &m.steps)
89+
moves = append(moves, m)
90+
}
91+
return moves
92+
}
93+
94+
func newKnot() *knot {
95+
k := &knot{visited: make(map[pos]bool)}
96+
k.move(pos{})
97+
return k
98+
}
99+
100+
var dirs = map[byte]pos{'U': {0, -1}, 'D': {0, 1}, 'L': {-1, 0}, 'R': {1, 0}}

0 commit comments

Comments
 (0)