4
4
"fmt"
5
5
"io"
6
6
"log"
7
+ "math"
7
8
"os"
8
9
"strconv"
9
10
"strings"
@@ -13,6 +14,10 @@ type Point struct {
13
14
X , Y int
14
15
}
15
16
17
+ func (c * Point ) String () string {
18
+ return fmt .Sprintf ("%d,%d" , c .X , c .Y )
19
+ }
20
+
16
21
func main () {
17
22
positionVisitedByTail , err := MoveRope (os .Stdin , (len (os .Args ) >= 2 && os .Args [1 ] == "debug" ))
18
23
if err != nil {
@@ -28,6 +33,8 @@ func MoveRope(input io.Reader, debug bool) (positionVisitedByTail int, err error
28
33
29
34
positionsVisited := []* Point {}
30
35
36
+ pointsVisited := map [string ]struct {}{}
37
+
31
38
err = IterateLines (input , func (s string ) Step {
32
39
direction := ""
33
40
distance := 0
@@ -52,13 +59,20 @@ func MoveRope(input io.Reader, debug bool) (positionVisitedByTail int, err error
52
59
53
60
move := DrawGrid (head , tail , []* Point {})
54
61
55
- x , y := Follow (tail , head )
56
- tail .X += x
57
- tail .Y += y
62
+ // x := tail.X
63
+ // y := tail.Y
64
+
65
+ Follow (head , tail )
58
66
59
- if x != 0 || y != 0 { // tail moved
67
+ // if x != tail.X || y != tail.Y { // tail moved
68
+ // positionsVisited = append(positionsVisited, &Point{X: tail.X, Y: tail.Y})
69
+ // positionVisitedByTail++
70
+ // }
71
+
72
+ if _ , ok := pointsVisited [tail .String ()]; ! ok {
73
+ pointsVisited [tail .String ()] = struct {}{}
60
74
positionsVisited = append (positionsVisited , & Point {X : tail .X , Y : tail .Y })
61
- positionVisitedByTail ++
75
+ positionVisitedByTail = len ( positionsVisited )
62
76
}
63
77
64
78
if debug {
@@ -78,6 +92,42 @@ func MoveRope(input io.Reader, debug bool) (positionVisitedByTail int, err error
78
92
return
79
93
}
80
94
95
+ func Follow (head * Point , tail * Point ) {
96
+ // If the head is right next to or directly on top of the tail then we do nothing
97
+ diffInX := math .Abs (float64 (tail .X - head .X ))
98
+ diffInY := math .Abs (float64 (tail .Y - head .Y ))
99
+
100
+ if diffInY <= 1 && diffInX <= 1 {
101
+ return
102
+ }
103
+
104
+ //fmt.Println(fmt.Sprintf("Tail moving (%s) to meet head (%s)", tail.String(), head.String()))
105
+ xDirection := 1
106
+ yDirection := 1
107
+
108
+ if head .Y < tail .Y {
109
+ yDirection = - 1
110
+ }
111
+
112
+ if head .X < tail .X {
113
+ xDirection = - 1
114
+ }
115
+
116
+ if head .X == tail .X {
117
+ tail .Y += 1 * yDirection
118
+ return
119
+ }
120
+
121
+ if head .Y == tail .Y {
122
+ tail .X += 1 * xDirection
123
+ return
124
+ }
125
+
126
+ // Diagonal
127
+ tail .X += 1 * xDirection
128
+ tail .Y += 1 * yDirection
129
+ }
130
+
81
131
func DrawGrid (head * Point , tail * Point , otherPoints []* Point ) * strings.Builder {
82
132
var strBuilder = & strings.Builder {}
83
133
@@ -114,33 +164,3 @@ func DrawGrid(head *Point, tail *Point, otherPoints []*Point) *strings.Builder {
114
164
115
165
return strBuilder
116
166
}
117
-
118
- func Follow (point * Point , target * Point ) (x , y int ) {
119
- // only follow if distance between two point is greater then 1
120
- if point .X == target .X && point .Y == target .Y {
121
- return 0 , 0
122
- }
123
-
124
- // check if adjacent
125
- for tx := - 1 ; tx <= 1 ; tx ++ {
126
- for ty := - 1 ; ty <= 1 ; ty ++ {
127
- if point .X + tx == target .X && point .Y + ty == target .Y {
128
- return 0 , 0
129
- }
130
- }
131
- }
132
-
133
- if point .X < target .X {
134
- x = 1
135
- } else if point .X > target .X {
136
- x = - 1
137
- }
138
-
139
- if point .Y < target .Y {
140
- y = 1
141
- } else if point .Y > target .Y {
142
- y = - 1
143
- }
144
-
145
- return
146
- }
0 commit comments