Browse Source

Day 17, a bit messy.

master
Chris Smith 4 years ago
parent
commit
cec4d704b0
Signed by: Chris Smith <chris@chameth.com> GPG Key ID: 3A2D4BBDC4A3C9A9
6 changed files with 239 additions and 15 deletions
  1. 2
    13
      09/main.go
  2. 2
    2
      09/main_test.go
  3. 2
    0
      17/answers.txt
  4. 1
    0
      17/input.txt
  5. 219
    0
      17/main.go
  6. 13
    0
      common/channels.go

+ 2
- 13
09/main.go View File

@@ -5,17 +5,6 @@ import (
5 5
 	"github.com/csmith/aoc-2019/intcode"
6 6
 )
7 7
 
8
-func last(channel <-chan int) (res int) {
9
-	for {
10
-		o, more := <-channel
11
-		if more {
12
-			res = o
13
-		} else {
14
-			return
15
-		}
16
-	}
17
-}
18
-
19 8
 func main() {
20 9
 	input := common.ReadCsvAsInts("09/input.txt")
21 10
 	memory := make([]int, len(input))
@@ -26,12 +15,12 @@ func main() {
26 15
 	vm.Output = make(chan int, 1)
27 16
 	vm.Input <- 1
28 17
 	go vm.Run()
29
-	println(last(vm.Output))
18
+	println(common.Last(vm.Output))
30 19
 
31 20
 	vm.Reset(input)
32 21
 	vm.Input = make(chan int, 1)
33 22
 	vm.Output = make(chan int, 1)
34 23
 	vm.Input <- 2
35 24
 	go vm.Run()
36
-	println(last(vm.Output))
25
+	println(common.Last(vm.Output))
37 26
 }

+ 2
- 2
09/main_test.go View File

@@ -17,7 +17,7 @@ func Benchmark_Part1(b *testing.B) {
17 17
 		vm.Output = make(chan int, 1)
18 18
 		vm.Input <- 1
19 19
 		go vm.Run()
20
-		_ = last(vm.Output)
20
+		_ = common.Last(vm.Output)
21 21
 	}
22 22
 }
23 23
 
@@ -32,6 +32,6 @@ func Benchmark_Part2(b *testing.B) {
32 32
 		vm.Output = make(chan int, 1)
33 33
 		vm.Input <- 2
34 34
 		go vm.Run()
35
-		_ = last(vm.Output)
35
+		_ = common.Last(vm.Output)
36 36
 	}
37 37
 }

+ 2
- 0
17/answers.txt View File

@@ -0,0 +1,2 @@
1
+3608
2
+897426

+ 1
- 0
17/input.txt View File

@@ -0,0 +1 @@
1
+1,330,331,332,109,3072,1101,1182,0,16,1101,1481,0,24,102,1,0,570,1006,570,36,1002,571,1,0,1001,570,-1,570,1001,24,1,24,1105,1,18,1008,571,0,571,1001,16,1,16,1008,16,1481,570,1006,570,14,21101,0,58,0,1105,1,786,1006,332,62,99,21101,333,0,1,21102,1,73,0,1105,1,579,1102,1,0,572,1101,0,0,573,3,574,101,1,573,573,1007,574,65,570,1005,570,151,107,67,574,570,1005,570,151,1001,574,-64,574,1002,574,-1,574,1001,572,1,572,1007,572,11,570,1006,570,165,101,1182,572,127,101,0,574,0,3,574,101,1,573,573,1008,574,10,570,1005,570,189,1008,574,44,570,1006,570,158,1106,0,81,21102,1,340,1,1105,1,177,21101,0,477,1,1105,1,177,21102,1,514,1,21102,1,176,0,1105,1,579,99,21101,0,184,0,1105,1,579,4,574,104,10,99,1007,573,22,570,1006,570,165,1002,572,1,1182,21101,0,375,1,21101,211,0,0,1105,1,579,21101,1182,11,1,21102,222,1,0,1106,0,979,21102,1,388,1,21102,1,233,0,1106,0,579,21101,1182,22,1,21101,0,244,0,1106,0,979,21102,401,1,1,21102,1,255,0,1105,1,579,21101,1182,33,1,21101,266,0,0,1106,0,979,21101,414,0,1,21102,277,1,0,1105,1,579,3,575,1008,575,89,570,1008,575,121,575,1,575,570,575,3,574,1008,574,10,570,1006,570,291,104,10,21102,1182,1,1,21102,313,1,0,1105,1,622,1005,575,327,1101,1,0,575,21101,0,327,0,1105,1,786,4,438,99,0,1,1,6,77,97,105,110,58,10,33,10,69,120,112,101,99,116,101,100,32,102,117,110,99,116,105,111,110,32,110,97,109,101,32,98,117,116,32,103,111,116,58,32,0,12,70,117,110,99,116,105,111,110,32,65,58,10,12,70,117,110,99,116,105,111,110,32,66,58,10,12,70,117,110,99,116,105,111,110,32,67,58,10,23,67,111,110,116,105,110,117,111,117,115,32,118,105,100,101,111,32,102,101,101,100,63,10,0,37,10,69,120,112,101,99,116,101,100,32,82,44,32,76,44,32,111,114,32,100,105,115,116,97,110,99,101,32,98,117,116,32,103,111,116,58,32,36,10,69,120,112,101,99,116,101,100,32,99,111,109,109,97,32,111,114,32,110,101,119,108,105,110,101,32,98,117,116,32,103,111,116,58,32,43,10,68,101,102,105,110,105,116,105,111,110,115,32,109,97,121,32,98,101,32,97,116,32,109,111,115,116,32,50,48,32,99,104,97,114,97,99,116,101,114,115,33,10,94,62,118,60,0,1,0,-1,-1,0,1,0,0,0,0,0,0,1,28,0,0,109,4,1202,-3,1,587,20101,0,0,-1,22101,1,-3,-3,21101,0,0,-2,2208,-2,-1,570,1005,570,617,2201,-3,-2,609,4,0,21201,-2,1,-2,1106,0,597,109,-4,2106,0,0,109,5,1202,-4,1,630,20102,1,0,-2,22101,1,-4,-4,21102,0,1,-3,2208,-3,-2,570,1005,570,781,2201,-4,-3,652,21001,0,0,-1,1208,-1,-4,570,1005,570,709,1208,-1,-5,570,1005,570,734,1207,-1,0,570,1005,570,759,1206,-1,774,1001,578,562,684,1,0,576,576,1001,578,566,692,1,0,577,577,21101,0,702,0,1105,1,786,21201,-1,-1,-1,1106,0,676,1001,578,1,578,1008,578,4,570,1006,570,724,1001,578,-4,578,21102,731,1,0,1105,1,786,1106,0,774,1001,578,-1,578,1008,578,-1,570,1006,570,749,1001,578,4,578,21102,1,756,0,1105,1,786,1106,0,774,21202,-1,-11,1,22101,1182,1,1,21101,0,774,0,1106,0,622,21201,-3,1,-3,1106,0,640,109,-5,2106,0,0,109,7,1005,575,802,20102,1,576,-6,20102,1,577,-5,1105,1,814,21101,0,0,-1,21101,0,0,-5,21101,0,0,-6,20208,-6,576,-2,208,-5,577,570,22002,570,-2,-2,21202,-5,37,-3,22201,-6,-3,-3,22101,1481,-3,-3,1201,-3,0,843,1005,0,863,21202,-2,42,-4,22101,46,-4,-4,1206,-2,924,21101,1,0,-1,1106,0,924,1205,-2,873,21102,1,35,-4,1106,0,924,1201,-3,0,878,1008,0,1,570,1006,570,916,1001,374,1,374,2101,0,-3,895,1102,2,1,0,2102,1,-3,902,1001,438,0,438,2202,-6,-5,570,1,570,374,570,1,570,438,438,1001,578,558,921,21002,0,1,-4,1006,575,959,204,-4,22101,1,-6,-6,1208,-6,37,570,1006,570,814,104,10,22101,1,-5,-5,1208,-5,43,570,1006,570,810,104,10,1206,-1,974,99,1206,-1,974,1101,0,1,575,21101,0,973,0,1106,0,786,99,109,-7,2105,1,0,109,6,21101,0,0,-4,21101,0,0,-3,203,-2,22101,1,-3,-3,21208,-2,82,-1,1205,-1,1030,21208,-2,76,-1,1205,-1,1037,21207,-2,48,-1,1205,-1,1124,22107,57,-2,-1,1205,-1,1124,21201,-2,-48,-2,1105,1,1041,21102,-4,1,-2,1105,1,1041,21101,-5,0,-2,21201,-4,1,-4,21207,-4,11,-1,1206,-1,1138,2201,-5,-4,1059,1201,-2,0,0,203,-2,22101,1,-3,-3,21207,-2,48,-1,1205,-1,1107,22107,57,-2,-1,1205,-1,1107,21201,-2,-48,-2,2201,-5,-4,1090,20102,10,0,-1,22201,-2,-1,-2,2201,-5,-4,1103,1201,-2,0,0,1106,0,1060,21208,-2,10,-1,1205,-1,1162,21208,-2,44,-1,1206,-1,1131,1105,1,989,21101,439,0,1,1105,1,1150,21102,1,477,1,1106,0,1150,21101,514,0,1,21101,0,1149,0,1105,1,579,99,21101,1157,0,0,1105,1,579,204,-2,104,10,99,21207,-3,22,-1,1206,-1,1138,1201,-5,0,1176,2101,0,-4,0,109,-6,2106,0,0,28,9,36,1,36,1,36,1,36,1,36,1,26,9,1,1,26,1,7,1,1,1,22,11,1,1,1,1,22,1,3,1,5,1,1,1,1,1,2,13,7,1,3,11,2,1,11,1,7,1,9,1,1,1,4,1,11,1,7,1,9,1,1,1,4,1,11,1,7,1,9,1,1,1,4,1,5,13,1,1,9,1,1,1,4,1,5,1,5,1,5,1,1,1,9,1,1,1,2,11,3,1,5,1,1,13,2,1,1,1,5,1,1,1,3,1,5,1,11,1,4,1,1,1,5,1,1,1,3,1,5,13,4,1,1,1,5,1,1,1,3,1,22,1,1,9,3,1,15,1,6,1,7,1,5,1,15,1,6,1,7,1,1,5,15,1,6,1,7,1,1,1,19,1,6,1,7,1,1,1,19,1,6,1,7,1,1,1,19,1,6,9,1,1,19,1,16,1,19,1,12,13,11,1,12,1,3,1,7,1,11,1,12,1,3,1,7,1,11,1,12,1,3,1,7,1,11,1,12,1,3,1,1,5,1,13,12,1,3,1,1,1,3,1,26,1,3,13,20,1,5,1,3,1,5,1,20,1,5,1,3,1,5,1,20,1,5,1,3,1,5,1,20,1,5,1,3,1,5,1,20,1,5,1,3,1,5,1,20,11,5,1,26,1,9,1,26,11,14

+ 219
- 0
17/main.go View File

@@ -0,0 +1,219 @@
1
+package main
2
+
3
+import (
4
+	"fmt"
5
+	"github.com/csmith/aoc-2019/common"
6
+	"github.com/csmith/aoc-2019/intcode"
7
+	"strconv"
8
+	"strings"
9
+)
10
+
11
+const (
12
+	up     = '^'
13
+	down   = 'v'
14
+	left   = '<'
15
+	right  = '>'
16
+	borked = 'X'
17
+)
18
+
19
+func rotate(from, to rune) rune {
20
+	if from == up && to == left || from == left && to == down || from == down && to == right || from == right && to == up {
21
+		return 'L'
22
+	} else {
23
+		return 'R'
24
+	}
25
+}
26
+
27
+func next(picture [][]rune, x, y int, direction rune) (nextDirection, turn rune) {
28
+	if x > 0 && direction != right && picture[y][x-1] == '#' {
29
+		nextDirection = left
30
+	} else if x < len(picture[0])-1 && direction != left && picture[y][x+1] == '#' {
31
+		nextDirection = right
32
+	} else if y > 0 && direction != down && picture[y-1][x] == '#' {
33
+		nextDirection = up
34
+	} else if y < len(picture)-1 && direction != up && picture[y+1][x] == '#' {
35
+		nextDirection = down
36
+	} else {
37
+		return borked, borked
38
+	}
39
+
40
+	return nextDirection, rotate(direction, nextDirection)
41
+}
42
+
43
+func follow(picture [][]rune, x, y int, direction rune) (int, int, int) {
44
+	deltaX, deltaY := 0, 0
45
+	switch direction {
46
+	case up:
47
+		deltaY = -1
48
+	case down:
49
+		deltaY = 1
50
+	case left:
51
+		deltaX = -1
52
+	case right:
53
+		deltaX = +1
54
+	case borked:
55
+		return x, y, borked
56
+	}
57
+
58
+	length := 0
59
+	for x+deltaX >= 0 && x+deltaX <= len(picture[0])-1 && y+deltaY >= 0 && y+deltaY <= len(picture)-1 && picture[y+deltaY][x+deltaX] == '#' {
60
+		x += deltaX
61
+		y += deltaY
62
+		length++
63
+	}
64
+
65
+	return x, y, length
66
+}
67
+
68
+func compactPass(movement string) string {
69
+	start := 0
70
+	for movement[start] == 'A' || movement[start] == 'B' {
71
+		start += 2
72
+	}
73
+
74
+	end := start + 4
75
+	for movement[end] != ',' {
76
+		end++
77
+	}
78
+
79
+	count := strings.Count(movement, movement[start:end])
80
+
81
+	for {
82
+		newEnd := end + 1
83
+		for movement[newEnd] != ',' {
84
+			newEnd++
85
+		}
86
+		if movement[newEnd-1] == 'A' || movement[newEnd-1] == 'B' {
87
+			break
88
+		}
89
+
90
+		newCount := strings.Count(movement, movement[start:end])
91
+		if newCount == count {
92
+			end = newEnd
93
+		} else {
94
+			break
95
+		}
96
+	}
97
+
98
+	return movement[start:end]
99
+}
100
+
101
+func compact(movement string) (main, a, b, c string) {
102
+	main = movement
103
+
104
+	a = compactPass(main)
105
+	main = strings.ReplaceAll(main, a, "A")
106
+
107
+	b = compactPass(main)
108
+	main = strings.ReplaceAll(main, b, "B")
109
+
110
+	c = compactPass(main)
111
+	main = strings.ReplaceAll(main, c, "C")
112
+	return
113
+}
114
+
115
+func readPicture(memory []int) [][]rune {
116
+	vm := intcode.NewVirtualMachine(memory)
117
+	vm.Input = make(chan int, 1)
118
+	vm.Output = make(chan int, 1)
119
+	go vm.Run()
120
+
121
+	var picture [][]rune
122
+	var currentRow []rune
123
+	for {
124
+		char, more := <-vm.Output
125
+		if !more {
126
+			break
127
+		}
128
+
129
+		if char == '\n' && len(currentRow) > 0 {
130
+			picture = append(picture, currentRow)
131
+			currentRow = make([]rune, 0)
132
+		} else {
133
+			currentRow = append(currentRow, rune(char))
134
+		}
135
+	}
136
+	return picture
137
+}
138
+
139
+func analysePicture(picture [][]rune) (sum int, robot rune, robotX, robotY int) {
140
+	robot = borked
141
+	for y, line := range picture {
142
+		for x, r := range line {
143
+			if r == '#' &&
144
+				x > 0 && line[x-1] == '#' &&
145
+				x < len(line)-1 && line[x+1] == '#' &&
146
+				y > 0 && picture[y-1][x] == '#' &&
147
+				y < len(picture)-1 && picture[y+1][x] == '#' {
148
+				sum += x * y
149
+			}
150
+
151
+			if r == up || r == down || r == left || r == right {
152
+				robotX = x
153
+				robotY = y
154
+				robot = r
155
+			}
156
+		}
157
+	}
158
+	return
159
+}
160
+
161
+func buildRoute(picture [][]rune, robot rune, robotX, robotY int) string {
162
+	var (
163
+		length       int
164
+		turn         rune
165
+		routeBuilder strings.Builder
166
+	)
167
+	for {
168
+		robot, turn = next(picture, robotX, robotY, robot)
169
+		robotX, robotY, length = follow(picture, robotX, robotY, robot)
170
+
171
+		if robot == borked {
172
+			break
173
+		}
174
+
175
+		if routeBuilder.Len() > 0 {
176
+			routeBuilder.WriteRune(',')
177
+		}
178
+		routeBuilder.WriteRune(turn)
179
+		routeBuilder.WriteString(strconv.Itoa(length))
180
+	}
181
+	return routeBuilder.String()
182
+}
183
+
184
+func calculateDust(input []int, m, a, b, c string) int {
185
+	vm := intcode.NewVirtualMachine(input)
186
+	vm.Input = make(chan int, 1)
187
+	vm.Output = make(chan int, 1)
188
+	vm.Memory[0] = 2
189
+	go vm.Run()
190
+
191
+	go func() {
192
+		for _, line := range []string{m, a, b, c, "n"} {
193
+			for _, r := range line {
194
+				vm.Input <- int(r)
195
+				if r == 'L' || r == 'R' {
196
+					vm.Input <- ','
197
+				}
198
+			}
199
+			vm.Input <- '\n'
200
+		}
201
+	}()
202
+
203
+	return common.Last(vm.Output)
204
+}
205
+
206
+func main() {
207
+	input := common.ReadCsvAsInts("17/input.txt")
208
+	memory := make([]int, len(input))
209
+	copy(memory, input)
210
+
211
+	picture := readPicture(input)
212
+	sum, robot, robotX, robotY := analysePicture(picture)
213
+	route := buildRoute(picture, robot, robotX, robotY)
214
+	m, a, b, c := compact(route)
215
+	dust := calculateDust(memory, m, a, b, c)
216
+
217
+	fmt.Println(sum)
218
+	fmt.Println(dust)
219
+}

+ 13
- 0
common/channels.go View File

@@ -0,0 +1,13 @@
1
+package common
2
+
3
+// Last returns the last value received from the channel before it was closed
4
+func Last(channel <-chan int) (res int) {
5
+	for {
6
+		o, more := <-channel
7
+		if more {
8
+			res = o
9
+		} else {
10
+			return
11
+		}
12
+	}
13
+}

Loading…
Cancel
Save