1
1
package main
2
2
3
3
import (
4
+ "bytes"
4
5
"fmt"
5
6
"io"
7
+ "io/ioutil"
6
8
"log"
7
9
"math"
8
10
"os"
9
11
"strconv"
10
12
"strings"
11
13
)
12
14
15
+ // 6181
16
+
13
17
type Point struct {
14
18
X , Y int
15
19
}
@@ -19,19 +23,33 @@ func (c *Point) String() string {
19
23
}
20
24
21
25
func main () {
22
- positionVisitedByTail , err := MoveRope (os .Stdin , (len (os .Args ) >= 2 && os .Args [1 ] == "debug" ))
26
+ rawBody , err := ioutil .ReadAll (os .Stdin )
27
+ if err != nil {
28
+ panic (err )
29
+ }
30
+
31
+ positionVisitedByTail , err := MoveRope (ioutil .NopCloser (bytes .NewBuffer (rawBody )), (len (os .Args ) >= 2 && os .Args [1 ] == "debug" ), 1 )
23
32
if err != nil {
24
33
log .Fatal (err )
25
34
}
26
35
27
36
fmt .Printf ("Part 1: %d\n " , positionVisitedByTail )
37
+
38
+ x , err := MoveRope (ioutil .NopCloser (bytes .NewBuffer (rawBody )), (len (os .Args ) >= 2 && os .Args [1 ] == "debug" ), 9 )
39
+ if err != nil {
40
+ log .Fatal (err )
41
+ }
42
+
43
+ fmt .Printf ("Part 2: %d\n " , x )
28
44
}
29
45
30
- func MoveRope (input io.Reader , debug bool ) (positionVisitedByTail int , err error ) {
46
+ func MoveRope (input io.Reader , debug bool , tailSize int ) (positionVisitedByTail int , err error ) {
31
47
head := & Point {X : 0 , Y : 0 }
32
- tail := & Point {X : 0 , Y : 0 }
48
+ tail := [] * Point {}
33
49
34
- positionsVisited := []* Point {}
50
+ for i := 0 ; i < tailSize ; i ++ {
51
+ tail = append (tail , & Point {X : 0 , Y : 0 })
52
+ }
35
53
36
54
pointsVisited := map [string ]struct {}{}
37
55
@@ -45,7 +63,6 @@ func MoveRope(input io.Reader, debug bool) (positionVisitedByTail int, err error
45
63
}
46
64
47
65
for i := 0 ; i < distance ; i ++ {
48
-
49
66
switch direction {
50
67
case "U" :
51
68
head .Y ++
@@ -57,24 +74,19 @@ func MoveRope(input io.Reader, debug bool) (positionVisitedByTail int, err error
57
74
head .X ++
58
75
}
59
76
60
- move := DrawGrid (head , tail , []* Point {})
61
-
62
- Follow (head , tail )
63
-
64
- if _ , ok := pointsVisited [tail .String ()]; ! ok {
65
- pointsVisited [tail .String ()] = struct {}{}
66
- positionsVisited = append (positionsVisited , & Point {X : tail .X , Y : tail .Y })
67
- positionVisitedByTail = len (positionsVisited )
77
+ h := head
78
+ for i := 0 ; i < len (tail ); i ++ {
79
+ Follow (h , tail [i ])
80
+ h = tail [i ]
68
81
}
69
82
83
+ lastTail := tail [len (tail )- 1 ]
84
+ pointsVisited [lastTail .String ()] = struct {}{}
85
+ positionVisitedByTail = len (pointsVisited )
86
+
70
87
if debug {
71
88
fmt .Printf ("Head: %v, Tail: %v Direction: %s, Distance: %d/%d Positions: %d \n " , head , tail , direction , i + 1 , distance , positionVisitedByTail )
72
-
73
- fmt .Printf ("%s" , DrawLinesNextToEachOther (
74
- "Head:\n " + move .String (),
75
- "Tail:\n " + DrawGrid (head , tail , []* Point {}).String (),
76
- "visited:\n " + DrawGrid (nil , nil , positionsVisited ).String (),
77
- ))
89
+ fmt .Printf ("%s" , DrawGrid (head , tail ).String ())
78
90
}
79
91
}
80
92
@@ -93,7 +105,6 @@ func Follow(head *Point, tail *Point) {
93
105
return
94
106
}
95
107
96
- //fmt.Println(fmt.Sprintf("Tail moving (%s) to meet head (%s)", tail.String(), head.String()))
97
108
xDirection := 1
98
109
yDirection := 1
99
110
@@ -120,7 +131,7 @@ func Follow(head *Point, tail *Point) {
120
131
tail .Y += 1 * yDirection
121
132
}
122
133
123
- func DrawGrid (head * Point , tail * Point , otherPoints []* Point ) * strings.Builder {
134
+ func DrawGrid (head * Point , otherPoints []* Point ) * strings.Builder {
124
135
var strBuilder = & strings.Builder {}
125
136
126
137
const width = 6
@@ -131,15 +142,13 @@ func DrawGrid(head *Point, tail *Point, otherPoints []*Point) *strings.Builder {
131
142
for x := 0 ; x < width ; x ++ {
132
143
if head != nil && x == head .X && y == head .Y {
133
144
strBuilder .WriteString ("H" )
134
- } else if tail != nil && x == tail .X && y == tail .Y {
135
- strBuilder .WriteString ("T" )
136
145
} else if x == 0 && y == 0 {
137
146
strBuilder .WriteString ("s" )
138
147
} else {
139
148
match := false
140
- for _ , p := range otherPoints {
149
+ for i , p := range otherPoints {
141
150
if p .X == x && p .Y == y {
142
- strBuilder .WriteString ("#" )
151
+ strBuilder .WriteString (fmt . Sprintf ( "%d" , i + 1 ) )
143
152
match = true
144
153
break
145
154
}
0 commit comments