├── README.md ├── day-1-1 ├── day-1-1.test ├── input.txt ├── main.go ├── main_test.go ├── v1.cpu.pprof ├── v1.mem.pprof ├── v1.txt ├── v2.cpu.pprof ├── v2.mem.pprof ├── v2.txt ├── v3.cpu.pprof ├── v3.mem.pprof ├── v3.txt ├── v4.cpu.pprof ├── v4.mem.pprof └── v4.txt ├── day-1-2 ├── day-1-2.test ├── input.txt ├── main.go ├── main_test.go ├── v1.cpu.pprof ├── v1.mem.pprof └── v1.txt ├── day-2-1 ├── input.txt ├── main.go ├── main_test.go ├── v1.cpu.pprof ├── v1.mem.pprof └── v1.txt ├── day-2-2 ├── day-2-2.test ├── input.txt ├── main.go ├── main_test.go ├── v1.cpu.pprof ├── v1.mem.pprof └── v1.txt ├── day-3-1 ├── input.txt ├── main.go ├── main_test.go └── v1.go ├── day-3-2 ├── input.txt ├── main.go ├── main_test.go └── v1.go ├── day-4-1 ├── day-4-1.test ├── input.txt ├── main.go ├── main_test.go ├── v1.cpu.pprof ├── v1.go ├── v1.mem.prof └── v1.txt ├── day-4-2 ├── day-4-2.test ├── input.txt ├── main.go ├── main_test.go ├── v1.cpu.pprof ├── v1.go ├── v1.mem.pprof └── v1.txt ├── day-5-1 ├── cpu.pprof ├── day-5-1.test ├── input.txt ├── main.go ├── main_test.go ├── mem.pprof ├── v1.go └── v1.txt ├── day-5-2 ├── day-5-2.test ├── input.txt ├── main.go ├── main_test.go ├── v1.cpu.pprof ├── v1.go ├── v1.mem.pprof ├── v1.txt ├── v2.cpu.pprof ├── v2.go ├── v2.mem.pprof ├── v2.txt ├── v3.cpu.pprof ├── v3.go ├── v3.mem.pprof ├── v3.txt ├── v4.cpu.pprof ├── v4.go ├── v4.mem.pprof ├── v4.txt ├── v5.cpu.pprof ├── v5.go ├── v5.mem.pprof ├── v5.txt ├── v6.cpu.pprof ├── v6.go ├── v6.mem.pprof └── v6.txt ├── day-6-1 ├── day-6-1.test ├── input.txt ├── main.go ├── main_test.go ├── v1.cpu.pprof ├── v1.go ├── v1.mem.pprof └── v1.txt ├── day-6-2 ├── day-6-2.test ├── input.txt ├── main.go ├── main_test.go ├── v1.cpu.pprof ├── v1.go ├── v1.mem.pprof └── v1.txt ├── go.mod └── go.sum /README.md: -------------------------------------------------------------------------------- 1 | # advent-2021 2 | Advent of Go Profiling 2021. 3 | -------------------------------------------------------------------------------- /day-1-1/day-1-1.test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-1-1/day-1-1.test -------------------------------------------------------------------------------- /day-1-1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "strings" 8 | "unsafe" 9 | ) 10 | 11 | func main() { 12 | if err := run(); err != nil { 13 | fmt.Fprintln(os.Stderr, err) 14 | os.Exit(1) 15 | } 16 | } 17 | 18 | func run() error { 19 | input, err := ioutil.ReadAll(os.Stdin) 20 | if err != nil { 21 | return err 22 | } 23 | answer, err := Answer(strings.TrimSpace(string(input))) 24 | fmt.Printf("answer: %v\n", answer) 25 | return err 26 | } 27 | 28 | // Solution from Valentin Deleplace: https://twitter.com/val_deleplace/status/1466442802330488838 29 | 30 | func Answer(input string) (int, error) { 31 | var prev int64 = -9999 32 | var increases int = -1 33 | 34 | val := int64(0) 35 | for p, N := 0, len(input); p < N; p++ { 36 | c := input[p] 37 | notNl := boolToInt64(c != '\n') 38 | increases += int((^notNl & 1) * boolToInt64(val > prev)) 39 | prev = notNl*prev + val*(^notNl&1) 40 | val = notNl * ((val << 8) + int64(c)) 41 | } 42 | increases += int(boolToInt64(val > prev)) 43 | return increases, nil 44 | } 45 | 46 | func boolToInt64(b bool) int64 { 47 | return *(*int64)(unsafe.Pointer(&b)) & 1 48 | } 49 | -------------------------------------------------------------------------------- /day-1-1/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/matryer/is" 8 | ) 9 | 10 | var testInput = strings.TrimSpace(` 11 | 199 12 | 200 13 | 208 14 | 210 15 | 200 16 | 207 17 | 240 18 | 269 19 | 260 20 | 263 21 | `) 22 | 23 | func TestAnswer(t *testing.T) { 24 | is := is.New(t) 25 | answer, err := Answer(testInput) 26 | is.NoErr(err) 27 | is.Equal(answer, 7) 28 | } 29 | 30 | func BenchmarkAnswer(b *testing.B) { 31 | for i := 0; i < b.N; i++ { 32 | Answer(testInput) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /day-1-1/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-1-1/v1.cpu.pprof -------------------------------------------------------------------------------- /day-1-1/v1.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-1-1/v1.mem.pprof -------------------------------------------------------------------------------- /day-1-1/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-1-1 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 3486409 329.2 ns/op 6 | BenchmarkAnswer-6 3671895 323.5 ns/op 7 | BenchmarkAnswer-6 3619921 324.0 ns/op 8 | BenchmarkAnswer-6 3691440 321.6 ns/op 9 | BenchmarkAnswer-6 3684214 324.6 ns/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-1-1 7.592s 12 | -------------------------------------------------------------------------------- /day-1-1/v2.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-1-1/v2.cpu.pprof -------------------------------------------------------------------------------- /day-1-1/v2.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-1-1/v2.mem.pprof -------------------------------------------------------------------------------- /day-1-1/v2.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-1-1 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 6975350 166.3 ns/op 6 | BenchmarkAnswer-6 7136568 167.9 ns/op 7 | BenchmarkAnswer-6 7088379 170.8 ns/op 8 | BenchmarkAnswer-6 7171686 168.1 ns/op 9 | BenchmarkAnswer-6 7114681 166.8 ns/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-1-1 6.846s 12 | -------------------------------------------------------------------------------- /day-1-1/v3.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-1-1/v3.cpu.pprof -------------------------------------------------------------------------------- /day-1-1/v3.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-1-1/v3.mem.pprof -------------------------------------------------------------------------------- /day-1-1/v3.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-1-1 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 12646252 91.16 ns/op 6 | BenchmarkAnswer-6 12349341 91.29 ns/op 7 | BenchmarkAnswer-6 12762171 90.61 ns/op 8 | BenchmarkAnswer-6 13102954 94.57 ns/op 9 | BenchmarkAnswer-6 5378912 198.4 ns/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-1-1 6.392s 12 | -------------------------------------------------------------------------------- /day-1-1/v4.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-1-1/v4.cpu.pprof -------------------------------------------------------------------------------- /day-1-1/v4.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-1-1/v4.mem.pprof -------------------------------------------------------------------------------- /day-1-1/v4.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-1-1 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 81163154 13.71 ns/op 6 | BenchmarkAnswer-6 88283187 13.66 ns/op 7 | BenchmarkAnswer-6 87031576 13.91 ns/op 8 | BenchmarkAnswer-6 75265725 13.72 ns/op 9 | BenchmarkAnswer-6 87996208 13.81 ns/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-1-1 6.039s 12 | -------------------------------------------------------------------------------- /day-1-2/day-1-2.test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-1-2/day-1-2.test -------------------------------------------------------------------------------- /day-1-2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | if err := run(); err != nil { 12 | fmt.Fprintln(os.Stderr, err) 13 | os.Exit(1) 14 | } 15 | } 16 | 17 | func run() error { 18 | input, err := ioutil.ReadAll(os.Stdin) 19 | if err != nil { 20 | return err 21 | } 22 | answer, err := Answer(strings.TrimSpace(string(input)) + "\n") 23 | fmt.Printf("answer: %v\n", answer) 24 | return err 25 | } 26 | 27 | func Answer(input string) (int, error) { 28 | var increases int 29 | var prev []int 30 | var intVal int 31 | for _, c := range input { 32 | if c >= '0' && c <= '9' { 33 | intVal = intVal*10 + int(c-'0') 34 | } else if c == '\n' { 35 | prev = append(prev, intVal) 36 | if len(prev) >= 4 { 37 | window := prev[len(prev)-3:] 38 | prevWindow := prev[len(prev)-4 : len(prev)-1] 39 | if sum(window) > sum(prevWindow) { 40 | increases++ 41 | } 42 | } 43 | intVal = 0 44 | } else { 45 | return 0, fmt.Errorf("bad character in input stream: %q", c) 46 | } 47 | } 48 | return increases, nil 49 | } 50 | 51 | func sum(nums []int) (s int) { 52 | for _, v := range nums { 53 | s += v 54 | } 55 | return 56 | } 57 | -------------------------------------------------------------------------------- /day-1-2/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/matryer/is" 8 | ) 9 | 10 | var testInput = strings.TrimSpace(` 11 | 199 12 | 200 13 | 208 14 | 210 15 | 200 16 | 207 17 | 240 18 | 269 19 | 260 20 | 263 21 | `) + "\n" 22 | 23 | func TestAnswer(t *testing.T) { 24 | is := is.New(t) 25 | answer, err := Answer(testInput) 26 | is.NoErr(err) 27 | is.Equal(answer, 5) 28 | } 29 | 30 | func BenchmarkAnswer(b *testing.B) { 31 | for i := 0; i < b.N; i++ { 32 | Answer(testInput) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /day-1-2/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-1-2/v1.cpu.pprof -------------------------------------------------------------------------------- /day-1-2/v1.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-1-2/v1.mem.pprof -------------------------------------------------------------------------------- /day-1-2/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-1-2 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 4465159 262.4 ns/op 6 | BenchmarkAnswer-6 4463922 260.4 ns/op 7 | BenchmarkAnswer-6 4544709 260.2 ns/op 8 | BenchmarkAnswer-6 4524207 261.8 ns/op 9 | BenchmarkAnswer-6 4519270 261.3 ns/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-1-2 7.437s 12 | -------------------------------------------------------------------------------- /day-2-1/input.txt: -------------------------------------------------------------------------------- 1 | forward 3 2 | down 9 3 | forward 6 4 | down 3 5 | forward 8 6 | down 3 7 | down 4 8 | forward 3 9 | forward 5 10 | up 7 11 | forward 1 12 | forward 1 13 | forward 5 14 | down 8 15 | down 5 16 | forward 3 17 | forward 2 18 | forward 4 19 | down 7 20 | up 2 21 | up 2 22 | down 5 23 | down 5 24 | down 8 25 | down 2 26 | down 4 27 | forward 8 28 | forward 8 29 | up 2 30 | down 2 31 | up 8 32 | up 4 33 | forward 7 34 | up 8 35 | down 6 36 | forward 9 37 | forward 6 38 | forward 5 39 | up 1 40 | forward 6 41 | forward 8 42 | down 4 43 | forward 6 44 | up 8 45 | down 9 46 | forward 1 47 | down 1 48 | up 8 49 | down 5 50 | down 7 51 | forward 7 52 | up 8 53 | forward 4 54 | forward 5 55 | up 9 56 | down 4 57 | forward 4 58 | up 5 59 | down 6 60 | forward 3 61 | forward 2 62 | forward 3 63 | forward 6 64 | up 4 65 | up 7 66 | forward 6 67 | forward 2 68 | down 1 69 | forward 3 70 | forward 3 71 | forward 2 72 | down 6 73 | forward 2 74 | forward 4 75 | forward 9 76 | forward 1 77 | up 6 78 | forward 7 79 | down 6 80 | down 7 81 | forward 6 82 | up 4 83 | down 7 84 | up 9 85 | up 2 86 | down 6 87 | down 6 88 | forward 9 89 | down 2 90 | forward 5 91 | up 3 92 | up 6 93 | forward 3 94 | forward 3 95 | up 8 96 | forward 1 97 | forward 9 98 | forward 9 99 | up 6 100 | forward 3 101 | forward 2 102 | forward 8 103 | up 8 104 | forward 5 105 | up 6 106 | forward 9 107 | down 4 108 | down 5 109 | forward 7 110 | down 6 111 | forward 8 112 | up 9 113 | forward 2 114 | down 8 115 | up 4 116 | forward 7 117 | down 9 118 | forward 5 119 | forward 7 120 | down 4 121 | forward 3 122 | forward 7 123 | forward 4 124 | forward 7 125 | forward 4 126 | up 1 127 | down 1 128 | down 6 129 | up 4 130 | forward 2 131 | down 5 132 | down 8 133 | down 1 134 | up 2 135 | down 6 136 | down 3 137 | forward 5 138 | forward 5 139 | down 5 140 | forward 3 141 | forward 3 142 | down 9 143 | down 9 144 | up 5 145 | down 5 146 | down 3 147 | forward 2 148 | down 1 149 | up 6 150 | down 1 151 | down 3 152 | down 7 153 | forward 3 154 | forward 5 155 | forward 7 156 | up 9 157 | up 9 158 | down 1 159 | forward 2 160 | up 4 161 | down 1 162 | up 4 163 | forward 3 164 | forward 5 165 | down 2 166 | forward 7 167 | down 6 168 | down 2 169 | forward 7 170 | forward 7 171 | down 9 172 | up 4 173 | down 6 174 | down 1 175 | down 5 176 | down 5 177 | down 3 178 | down 1 179 | forward 9 180 | forward 4 181 | up 8 182 | down 1 183 | up 7 184 | down 7 185 | down 8 186 | up 2 187 | down 9 188 | down 2 189 | forward 3 190 | forward 6 191 | forward 5 192 | forward 2 193 | forward 6 194 | down 4 195 | forward 5 196 | up 5 197 | forward 3 198 | down 4 199 | forward 3 200 | down 4 201 | forward 9 202 | forward 7 203 | forward 9 204 | forward 7 205 | up 4 206 | down 3 207 | forward 5 208 | forward 9 209 | forward 9 210 | down 5 211 | forward 9 212 | down 1 213 | down 3 214 | forward 2 215 | forward 5 216 | forward 8 217 | down 6 218 | down 4 219 | forward 1 220 | up 6 221 | down 8 222 | up 4 223 | up 8 224 | forward 3 225 | down 3 226 | down 2 227 | forward 3 228 | forward 4 229 | down 9 230 | down 4 231 | forward 6 232 | up 5 233 | forward 6 234 | up 1 235 | down 3 236 | forward 9 237 | down 5 238 | down 4 239 | forward 9 240 | up 6 241 | forward 9 242 | forward 2 243 | down 1 244 | forward 7 245 | forward 5 246 | down 4 247 | forward 6 248 | down 6 249 | up 3 250 | up 8 251 | down 6 252 | forward 8 253 | forward 3 254 | down 6 255 | down 3 256 | down 3 257 | up 6 258 | up 6 259 | up 1 260 | forward 7 261 | up 2 262 | forward 5 263 | forward 5 264 | up 3 265 | forward 7 266 | up 3 267 | down 7 268 | down 1 269 | forward 9 270 | forward 7 271 | down 1 272 | forward 7 273 | forward 8 274 | forward 2 275 | down 1 276 | up 3 277 | down 6 278 | forward 5 279 | forward 4 280 | forward 2 281 | down 8 282 | forward 3 283 | down 9 284 | down 4 285 | up 9 286 | down 2 287 | down 6 288 | up 2 289 | up 9 290 | forward 1 291 | down 8 292 | forward 3 293 | down 4 294 | down 2 295 | forward 9 296 | forward 2 297 | down 3 298 | down 8 299 | down 7 300 | down 7 301 | up 2 302 | down 7 303 | down 2 304 | down 4 305 | forward 8 306 | forward 1 307 | down 5 308 | forward 2 309 | forward 1 310 | forward 6 311 | down 7 312 | forward 1 313 | down 4 314 | forward 1 315 | up 7 316 | down 7 317 | forward 2 318 | down 4 319 | forward 9 320 | up 1 321 | forward 7 322 | forward 3 323 | forward 3 324 | down 2 325 | down 6 326 | up 1 327 | down 1 328 | down 7 329 | forward 2 330 | forward 6 331 | down 5 332 | up 4 333 | down 9 334 | up 6 335 | forward 1 336 | forward 4 337 | down 9 338 | up 7 339 | down 8 340 | up 6 341 | down 8 342 | down 5 343 | down 5 344 | down 2 345 | forward 7 346 | forward 2 347 | up 2 348 | up 9 349 | forward 6 350 | down 9 351 | down 6 352 | forward 3 353 | down 8 354 | forward 3 355 | forward 2 356 | down 9 357 | forward 5 358 | up 3 359 | forward 5 360 | down 1 361 | up 1 362 | down 3 363 | forward 1 364 | forward 5 365 | down 7 366 | forward 8 367 | forward 6 368 | down 4 369 | down 9 370 | forward 5 371 | forward 2 372 | down 8 373 | down 3 374 | down 6 375 | down 2 376 | down 1 377 | forward 6 378 | forward 1 379 | forward 6 380 | up 9 381 | down 4 382 | up 7 383 | forward 5 384 | up 6 385 | down 3 386 | forward 6 387 | forward 3 388 | forward 2 389 | forward 2 390 | up 1 391 | down 9 392 | forward 2 393 | forward 3 394 | up 1 395 | forward 3 396 | forward 2 397 | down 4 398 | down 8 399 | up 9 400 | up 1 401 | forward 4 402 | up 2 403 | down 6 404 | forward 3 405 | down 5 406 | up 5 407 | up 7 408 | down 1 409 | forward 1 410 | forward 7 411 | down 4 412 | forward 4 413 | forward 2 414 | forward 8 415 | down 7 416 | down 8 417 | down 8 418 | forward 5 419 | forward 8 420 | down 5 421 | forward 3 422 | down 3 423 | down 1 424 | forward 2 425 | forward 7 426 | forward 2 427 | forward 6 428 | forward 3 429 | forward 7 430 | up 6 431 | down 5 432 | forward 6 433 | down 5 434 | down 7 435 | forward 6 436 | up 5 437 | down 9 438 | down 3 439 | forward 1 440 | forward 1 441 | forward 3 442 | down 9 443 | forward 1 444 | down 9 445 | down 9 446 | down 4 447 | down 2 448 | down 5 449 | up 6 450 | forward 1 451 | down 7 452 | down 2 453 | forward 9 454 | down 8 455 | down 2 456 | forward 7 457 | down 8 458 | forward 2 459 | up 8 460 | up 6 461 | forward 9 462 | down 7 463 | forward 1 464 | down 4 465 | down 7 466 | forward 1 467 | forward 4 468 | down 1 469 | forward 9 470 | down 1 471 | up 2 472 | up 4 473 | forward 3 474 | down 4 475 | forward 7 476 | forward 1 477 | up 7 478 | up 4 479 | forward 7 480 | forward 2 481 | forward 5 482 | down 7 483 | down 9 484 | forward 4 485 | forward 6 486 | down 9 487 | forward 6 488 | up 8 489 | forward 3 490 | forward 2 491 | forward 3 492 | forward 9 493 | down 7 494 | down 4 495 | down 7 496 | down 7 497 | down 5 498 | forward 7 499 | down 1 500 | forward 3 501 | up 3 502 | down 1 503 | up 7 504 | up 7 505 | up 4 506 | forward 9 507 | down 8 508 | up 4 509 | forward 6 510 | forward 8 511 | down 8 512 | forward 1 513 | down 6 514 | forward 1 515 | forward 4 516 | up 8 517 | forward 3 518 | up 6 519 | up 1 520 | down 4 521 | up 1 522 | forward 8 523 | up 1 524 | forward 7 525 | down 1 526 | up 9 527 | down 3 528 | forward 4 529 | down 6 530 | down 7 531 | forward 7 532 | forward 4 533 | down 1 534 | up 3 535 | forward 3 536 | up 7 537 | up 9 538 | up 9 539 | forward 7 540 | down 8 541 | forward 5 542 | up 2 543 | forward 7 544 | forward 8 545 | down 2 546 | down 6 547 | down 1 548 | down 1 549 | down 5 550 | down 5 551 | up 5 552 | forward 1 553 | forward 3 554 | down 9 555 | down 6 556 | forward 9 557 | forward 1 558 | down 4 559 | forward 7 560 | forward 6 561 | up 4 562 | down 8 563 | down 9 564 | forward 3 565 | down 9 566 | up 5 567 | forward 3 568 | up 1 569 | forward 3 570 | forward 1 571 | forward 8 572 | up 6 573 | down 6 574 | forward 9 575 | forward 7 576 | forward 8 577 | down 1 578 | forward 9 579 | forward 1 580 | forward 3 581 | forward 6 582 | down 1 583 | down 9 584 | down 9 585 | forward 1 586 | down 2 587 | down 5 588 | forward 7 589 | forward 6 590 | down 5 591 | forward 8 592 | forward 1 593 | forward 5 594 | forward 6 595 | down 6 596 | down 9 597 | down 7 598 | forward 7 599 | down 2 600 | down 2 601 | up 2 602 | forward 9 603 | forward 4 604 | forward 2 605 | up 9 606 | forward 3 607 | forward 1 608 | forward 6 609 | down 4 610 | down 9 611 | down 9 612 | down 1 613 | down 3 614 | down 1 615 | forward 5 616 | down 7 617 | forward 9 618 | forward 7 619 | forward 4 620 | forward 7 621 | forward 8 622 | forward 5 623 | down 8 624 | down 1 625 | up 1 626 | forward 9 627 | forward 9 628 | down 4 629 | up 7 630 | up 3 631 | down 1 632 | forward 5 633 | forward 2 634 | down 6 635 | down 6 636 | up 3 637 | down 6 638 | up 7 639 | forward 2 640 | forward 2 641 | forward 8 642 | down 3 643 | up 5 644 | down 4 645 | forward 5 646 | down 4 647 | forward 8 648 | down 5 649 | down 2 650 | forward 6 651 | down 2 652 | down 3 653 | down 5 654 | up 6 655 | down 7 656 | forward 6 657 | forward 2 658 | down 8 659 | up 1 660 | up 1 661 | forward 2 662 | down 3 663 | forward 3 664 | down 8 665 | down 4 666 | forward 1 667 | down 2 668 | forward 6 669 | up 3 670 | forward 8 671 | down 6 672 | up 7 673 | forward 2 674 | forward 9 675 | forward 4 676 | forward 4 677 | up 7 678 | forward 6 679 | up 1 680 | forward 1 681 | forward 3 682 | down 4 683 | up 7 684 | forward 8 685 | forward 4 686 | down 8 687 | forward 4 688 | down 8 689 | forward 9 690 | down 3 691 | down 4 692 | up 6 693 | up 1 694 | forward 7 695 | up 3 696 | forward 5 697 | forward 4 698 | forward 5 699 | forward 7 700 | forward 1 701 | down 3 702 | up 5 703 | forward 7 704 | forward 4 705 | down 9 706 | down 6 707 | down 7 708 | up 3 709 | up 7 710 | up 8 711 | up 9 712 | down 4 713 | up 1 714 | forward 1 715 | up 3 716 | forward 6 717 | down 8 718 | forward 4 719 | down 7 720 | down 5 721 | down 4 722 | forward 7 723 | forward 5 724 | down 4 725 | down 7 726 | up 5 727 | down 2 728 | down 1 729 | down 8 730 | forward 7 731 | down 4 732 | forward 5 733 | up 9 734 | down 3 735 | up 2 736 | down 3 737 | forward 2 738 | forward 2 739 | forward 8 740 | down 2 741 | down 3 742 | forward 2 743 | down 6 744 | forward 9 745 | down 6 746 | down 1 747 | down 8 748 | down 3 749 | forward 4 750 | forward 4 751 | forward 4 752 | up 8 753 | forward 8 754 | up 4 755 | down 1 756 | forward 5 757 | down 9 758 | forward 7 759 | up 9 760 | up 3 761 | down 9 762 | down 8 763 | forward 3 764 | forward 4 765 | forward 5 766 | forward 4 767 | up 7 768 | down 2 769 | up 5 770 | forward 6 771 | down 3 772 | forward 6 773 | down 8 774 | down 3 775 | down 3 776 | down 4 777 | forward 8 778 | down 9 779 | down 2 780 | forward 2 781 | down 7 782 | forward 3 783 | up 2 784 | forward 4 785 | down 8 786 | forward 2 787 | forward 9 788 | forward 3 789 | down 6 790 | forward 9 791 | down 7 792 | forward 1 793 | forward 2 794 | forward 4 795 | forward 4 796 | up 4 797 | up 2 798 | down 7 799 | forward 9 800 | forward 9 801 | forward 7 802 | up 7 803 | down 2 804 | down 9 805 | forward 8 806 | down 5 807 | up 2 808 | down 6 809 | forward 9 810 | up 3 811 | down 5 812 | down 4 813 | forward 9 814 | forward 3 815 | down 6 816 | down 8 817 | up 5 818 | up 3 819 | down 2 820 | forward 9 821 | down 3 822 | forward 6 823 | down 9 824 | forward 5 825 | down 6 826 | up 6 827 | down 6 828 | forward 6 829 | forward 1 830 | down 3 831 | down 3 832 | up 8 833 | forward 1 834 | forward 4 835 | up 2 836 | forward 3 837 | forward 1 838 | forward 8 839 | forward 7 840 | down 7 841 | down 4 842 | down 6 843 | down 2 844 | forward 3 845 | down 2 846 | forward 6 847 | up 3 848 | down 9 849 | down 2 850 | forward 6 851 | down 6 852 | forward 5 853 | forward 2 854 | up 4 855 | forward 5 856 | up 5 857 | up 5 858 | up 3 859 | forward 9 860 | down 7 861 | forward 4 862 | down 7 863 | up 5 864 | down 3 865 | forward 5 866 | forward 3 867 | down 7 868 | up 2 869 | down 5 870 | forward 9 871 | forward 7 872 | up 7 873 | forward 5 874 | up 5 875 | down 1 876 | up 7 877 | forward 9 878 | down 8 879 | forward 2 880 | forward 8 881 | down 7 882 | down 3 883 | down 1 884 | up 7 885 | forward 4 886 | down 3 887 | forward 1 888 | forward 1 889 | forward 6 890 | up 7 891 | up 1 892 | forward 2 893 | down 8 894 | down 4 895 | down 2 896 | down 6 897 | forward 5 898 | down 7 899 | down 8 900 | down 7 901 | down 5 902 | down 5 903 | forward 1 904 | down 9 905 | forward 5 906 | down 6 907 | down 9 908 | up 3 909 | down 4 910 | forward 3 911 | down 6 912 | up 6 913 | forward 8 914 | forward 8 915 | forward 2 916 | down 2 917 | up 1 918 | forward 6 919 | forward 6 920 | up 9 921 | up 4 922 | forward 9 923 | up 7 924 | up 6 925 | down 2 926 | down 3 927 | up 7 928 | down 7 929 | forward 4 930 | forward 8 931 | down 3 932 | forward 1 933 | down 2 934 | forward 9 935 | forward 4 936 | forward 6 937 | down 7 938 | up 9 939 | forward 9 940 | forward 1 941 | forward 2 942 | down 1 943 | down 8 944 | down 7 945 | forward 3 946 | down 4 947 | down 9 948 | forward 2 949 | up 2 950 | forward 3 951 | up 3 952 | down 9 953 | down 2 954 | forward 3 955 | down 3 956 | forward 7 957 | forward 6 958 | down 6 959 | down 7 960 | forward 2 961 | down 9 962 | up 3 963 | down 6 964 | forward 3 965 | down 2 966 | down 1 967 | up 6 968 | down 3 969 | down 3 970 | down 1 971 | down 5 972 | down 3 973 | up 4 974 | down 2 975 | forward 5 976 | down 2 977 | down 8 978 | down 2 979 | down 5 980 | forward 9 981 | forward 4 982 | down 4 983 | down 2 984 | down 8 985 | forward 9 986 | down 8 987 | forward 1 988 | up 6 989 | forward 6 990 | down 7 991 | down 1 992 | down 2 993 | down 8 994 | down 8 995 | up 8 996 | forward 6 997 | forward 8 998 | forward 9 999 | forward 2 1000 | forward 5 1001 | -------------------------------------------------------------------------------- /day-2-1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | if err := run(); err != nil { 13 | fmt.Fprintln(os.Stderr, err) 14 | os.Exit(1) 15 | } 16 | } 17 | 18 | func run() error { 19 | input, err := ioutil.ReadAll(os.Stdin) 20 | if err != nil { 21 | return err 22 | } 23 | answer, err := Answer(strings.TrimSpace(string(input))) 24 | fmt.Printf("answer: %v\n", answer) 25 | return err 26 | } 27 | 28 | func Answer(input string) (int, error) { 29 | var x, y int 30 | for _, line := range strings.Split(input, "\n") { 31 | parts := strings.Split(line, " ") 32 | if len(parts) != 2 { 33 | return 0, fmt.Errorf("bad line: %q", line) 34 | } 35 | amount, err := strconv.ParseInt(parts[1], 10, 64) 36 | if err != nil { 37 | return 0, fmt.Errorf("bad amount: %q: %s", parts, err) 38 | } 39 | switch parts[0] { 40 | case "forward": 41 | x += int(amount) 42 | case "down": 43 | y += int(amount) 44 | case "up": 45 | y -= int(amount) 46 | default: 47 | return 0, fmt.Errorf("bad command: %q", line) 48 | } 49 | } 50 | return x * y, nil 51 | } 52 | -------------------------------------------------------------------------------- /day-2-1/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/matryer/is" 8 | ) 9 | 10 | var testInput = strings.TrimSpace(` 11 | forward 5 12 | down 5 13 | forward 8 14 | up 3 15 | down 8 16 | forward 2 17 | `) 18 | 19 | func TestAnswer(t *testing.T) { 20 | is := is.New(t) 21 | answer, err := Answer(testInput) 22 | is.NoErr(err) 23 | is.Equal(answer, 150) 24 | } 25 | 26 | func BenchmarkAnswer(b *testing.B) { 27 | for i := 0; i < b.N; i++ { 28 | Answer(testInput) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /day-2-1/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-2-1/v1.cpu.pprof -------------------------------------------------------------------------------- /day-2-1/v1.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-2-1/v1.mem.pprof -------------------------------------------------------------------------------- /day-2-1/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-2-1 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 1831820 660.4 ns/op 6 | BenchmarkAnswer-6 1814794 660.3 ns/op 7 | BenchmarkAnswer-6 1797471 661.5 ns/op 8 | BenchmarkAnswer-6 1809973 661.2 ns/op 9 | BenchmarkAnswer-6 1816310 664.8 ns/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-2-1 9.558s 12 | -------------------------------------------------------------------------------- /day-2-2/day-2-2.test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-2-2/day-2-2.test -------------------------------------------------------------------------------- /day-2-2/input.txt: -------------------------------------------------------------------------------- 1 | forward 3 2 | down 9 3 | forward 6 4 | down 3 5 | forward 8 6 | down 3 7 | down 4 8 | forward 3 9 | forward 5 10 | up 7 11 | forward 1 12 | forward 1 13 | forward 5 14 | down 8 15 | down 5 16 | forward 3 17 | forward 2 18 | forward 4 19 | down 7 20 | up 2 21 | up 2 22 | down 5 23 | down 5 24 | down 8 25 | down 2 26 | down 4 27 | forward 8 28 | forward 8 29 | up 2 30 | down 2 31 | up 8 32 | up 4 33 | forward 7 34 | up 8 35 | down 6 36 | forward 9 37 | forward 6 38 | forward 5 39 | up 1 40 | forward 6 41 | forward 8 42 | down 4 43 | forward 6 44 | up 8 45 | down 9 46 | forward 1 47 | down 1 48 | up 8 49 | down 5 50 | down 7 51 | forward 7 52 | up 8 53 | forward 4 54 | forward 5 55 | up 9 56 | down 4 57 | forward 4 58 | up 5 59 | down 6 60 | forward 3 61 | forward 2 62 | forward 3 63 | forward 6 64 | up 4 65 | up 7 66 | forward 6 67 | forward 2 68 | down 1 69 | forward 3 70 | forward 3 71 | forward 2 72 | down 6 73 | forward 2 74 | forward 4 75 | forward 9 76 | forward 1 77 | up 6 78 | forward 7 79 | down 6 80 | down 7 81 | forward 6 82 | up 4 83 | down 7 84 | up 9 85 | up 2 86 | down 6 87 | down 6 88 | forward 9 89 | down 2 90 | forward 5 91 | up 3 92 | up 6 93 | forward 3 94 | forward 3 95 | up 8 96 | forward 1 97 | forward 9 98 | forward 9 99 | up 6 100 | forward 3 101 | forward 2 102 | forward 8 103 | up 8 104 | forward 5 105 | up 6 106 | forward 9 107 | down 4 108 | down 5 109 | forward 7 110 | down 6 111 | forward 8 112 | up 9 113 | forward 2 114 | down 8 115 | up 4 116 | forward 7 117 | down 9 118 | forward 5 119 | forward 7 120 | down 4 121 | forward 3 122 | forward 7 123 | forward 4 124 | forward 7 125 | forward 4 126 | up 1 127 | down 1 128 | down 6 129 | up 4 130 | forward 2 131 | down 5 132 | down 8 133 | down 1 134 | up 2 135 | down 6 136 | down 3 137 | forward 5 138 | forward 5 139 | down 5 140 | forward 3 141 | forward 3 142 | down 9 143 | down 9 144 | up 5 145 | down 5 146 | down 3 147 | forward 2 148 | down 1 149 | up 6 150 | down 1 151 | down 3 152 | down 7 153 | forward 3 154 | forward 5 155 | forward 7 156 | up 9 157 | up 9 158 | down 1 159 | forward 2 160 | up 4 161 | down 1 162 | up 4 163 | forward 3 164 | forward 5 165 | down 2 166 | forward 7 167 | down 6 168 | down 2 169 | forward 7 170 | forward 7 171 | down 9 172 | up 4 173 | down 6 174 | down 1 175 | down 5 176 | down 5 177 | down 3 178 | down 1 179 | forward 9 180 | forward 4 181 | up 8 182 | down 1 183 | up 7 184 | down 7 185 | down 8 186 | up 2 187 | down 9 188 | down 2 189 | forward 3 190 | forward 6 191 | forward 5 192 | forward 2 193 | forward 6 194 | down 4 195 | forward 5 196 | up 5 197 | forward 3 198 | down 4 199 | forward 3 200 | down 4 201 | forward 9 202 | forward 7 203 | forward 9 204 | forward 7 205 | up 4 206 | down 3 207 | forward 5 208 | forward 9 209 | forward 9 210 | down 5 211 | forward 9 212 | down 1 213 | down 3 214 | forward 2 215 | forward 5 216 | forward 8 217 | down 6 218 | down 4 219 | forward 1 220 | up 6 221 | down 8 222 | up 4 223 | up 8 224 | forward 3 225 | down 3 226 | down 2 227 | forward 3 228 | forward 4 229 | down 9 230 | down 4 231 | forward 6 232 | up 5 233 | forward 6 234 | up 1 235 | down 3 236 | forward 9 237 | down 5 238 | down 4 239 | forward 9 240 | up 6 241 | forward 9 242 | forward 2 243 | down 1 244 | forward 7 245 | forward 5 246 | down 4 247 | forward 6 248 | down 6 249 | up 3 250 | up 8 251 | down 6 252 | forward 8 253 | forward 3 254 | down 6 255 | down 3 256 | down 3 257 | up 6 258 | up 6 259 | up 1 260 | forward 7 261 | up 2 262 | forward 5 263 | forward 5 264 | up 3 265 | forward 7 266 | up 3 267 | down 7 268 | down 1 269 | forward 9 270 | forward 7 271 | down 1 272 | forward 7 273 | forward 8 274 | forward 2 275 | down 1 276 | up 3 277 | down 6 278 | forward 5 279 | forward 4 280 | forward 2 281 | down 8 282 | forward 3 283 | down 9 284 | down 4 285 | up 9 286 | down 2 287 | down 6 288 | up 2 289 | up 9 290 | forward 1 291 | down 8 292 | forward 3 293 | down 4 294 | down 2 295 | forward 9 296 | forward 2 297 | down 3 298 | down 8 299 | down 7 300 | down 7 301 | up 2 302 | down 7 303 | down 2 304 | down 4 305 | forward 8 306 | forward 1 307 | down 5 308 | forward 2 309 | forward 1 310 | forward 6 311 | down 7 312 | forward 1 313 | down 4 314 | forward 1 315 | up 7 316 | down 7 317 | forward 2 318 | down 4 319 | forward 9 320 | up 1 321 | forward 7 322 | forward 3 323 | forward 3 324 | down 2 325 | down 6 326 | up 1 327 | down 1 328 | down 7 329 | forward 2 330 | forward 6 331 | down 5 332 | up 4 333 | down 9 334 | up 6 335 | forward 1 336 | forward 4 337 | down 9 338 | up 7 339 | down 8 340 | up 6 341 | down 8 342 | down 5 343 | down 5 344 | down 2 345 | forward 7 346 | forward 2 347 | up 2 348 | up 9 349 | forward 6 350 | down 9 351 | down 6 352 | forward 3 353 | down 8 354 | forward 3 355 | forward 2 356 | down 9 357 | forward 5 358 | up 3 359 | forward 5 360 | down 1 361 | up 1 362 | down 3 363 | forward 1 364 | forward 5 365 | down 7 366 | forward 8 367 | forward 6 368 | down 4 369 | down 9 370 | forward 5 371 | forward 2 372 | down 8 373 | down 3 374 | down 6 375 | down 2 376 | down 1 377 | forward 6 378 | forward 1 379 | forward 6 380 | up 9 381 | down 4 382 | up 7 383 | forward 5 384 | up 6 385 | down 3 386 | forward 6 387 | forward 3 388 | forward 2 389 | forward 2 390 | up 1 391 | down 9 392 | forward 2 393 | forward 3 394 | up 1 395 | forward 3 396 | forward 2 397 | down 4 398 | down 8 399 | up 9 400 | up 1 401 | forward 4 402 | up 2 403 | down 6 404 | forward 3 405 | down 5 406 | up 5 407 | up 7 408 | down 1 409 | forward 1 410 | forward 7 411 | down 4 412 | forward 4 413 | forward 2 414 | forward 8 415 | down 7 416 | down 8 417 | down 8 418 | forward 5 419 | forward 8 420 | down 5 421 | forward 3 422 | down 3 423 | down 1 424 | forward 2 425 | forward 7 426 | forward 2 427 | forward 6 428 | forward 3 429 | forward 7 430 | up 6 431 | down 5 432 | forward 6 433 | down 5 434 | down 7 435 | forward 6 436 | up 5 437 | down 9 438 | down 3 439 | forward 1 440 | forward 1 441 | forward 3 442 | down 9 443 | forward 1 444 | down 9 445 | down 9 446 | down 4 447 | down 2 448 | down 5 449 | up 6 450 | forward 1 451 | down 7 452 | down 2 453 | forward 9 454 | down 8 455 | down 2 456 | forward 7 457 | down 8 458 | forward 2 459 | up 8 460 | up 6 461 | forward 9 462 | down 7 463 | forward 1 464 | down 4 465 | down 7 466 | forward 1 467 | forward 4 468 | down 1 469 | forward 9 470 | down 1 471 | up 2 472 | up 4 473 | forward 3 474 | down 4 475 | forward 7 476 | forward 1 477 | up 7 478 | up 4 479 | forward 7 480 | forward 2 481 | forward 5 482 | down 7 483 | down 9 484 | forward 4 485 | forward 6 486 | down 9 487 | forward 6 488 | up 8 489 | forward 3 490 | forward 2 491 | forward 3 492 | forward 9 493 | down 7 494 | down 4 495 | down 7 496 | down 7 497 | down 5 498 | forward 7 499 | down 1 500 | forward 3 501 | up 3 502 | down 1 503 | up 7 504 | up 7 505 | up 4 506 | forward 9 507 | down 8 508 | up 4 509 | forward 6 510 | forward 8 511 | down 8 512 | forward 1 513 | down 6 514 | forward 1 515 | forward 4 516 | up 8 517 | forward 3 518 | up 6 519 | up 1 520 | down 4 521 | up 1 522 | forward 8 523 | up 1 524 | forward 7 525 | down 1 526 | up 9 527 | down 3 528 | forward 4 529 | down 6 530 | down 7 531 | forward 7 532 | forward 4 533 | down 1 534 | up 3 535 | forward 3 536 | up 7 537 | up 9 538 | up 9 539 | forward 7 540 | down 8 541 | forward 5 542 | up 2 543 | forward 7 544 | forward 8 545 | down 2 546 | down 6 547 | down 1 548 | down 1 549 | down 5 550 | down 5 551 | up 5 552 | forward 1 553 | forward 3 554 | down 9 555 | down 6 556 | forward 9 557 | forward 1 558 | down 4 559 | forward 7 560 | forward 6 561 | up 4 562 | down 8 563 | down 9 564 | forward 3 565 | down 9 566 | up 5 567 | forward 3 568 | up 1 569 | forward 3 570 | forward 1 571 | forward 8 572 | up 6 573 | down 6 574 | forward 9 575 | forward 7 576 | forward 8 577 | down 1 578 | forward 9 579 | forward 1 580 | forward 3 581 | forward 6 582 | down 1 583 | down 9 584 | down 9 585 | forward 1 586 | down 2 587 | down 5 588 | forward 7 589 | forward 6 590 | down 5 591 | forward 8 592 | forward 1 593 | forward 5 594 | forward 6 595 | down 6 596 | down 9 597 | down 7 598 | forward 7 599 | down 2 600 | down 2 601 | up 2 602 | forward 9 603 | forward 4 604 | forward 2 605 | up 9 606 | forward 3 607 | forward 1 608 | forward 6 609 | down 4 610 | down 9 611 | down 9 612 | down 1 613 | down 3 614 | down 1 615 | forward 5 616 | down 7 617 | forward 9 618 | forward 7 619 | forward 4 620 | forward 7 621 | forward 8 622 | forward 5 623 | down 8 624 | down 1 625 | up 1 626 | forward 9 627 | forward 9 628 | down 4 629 | up 7 630 | up 3 631 | down 1 632 | forward 5 633 | forward 2 634 | down 6 635 | down 6 636 | up 3 637 | down 6 638 | up 7 639 | forward 2 640 | forward 2 641 | forward 8 642 | down 3 643 | up 5 644 | down 4 645 | forward 5 646 | down 4 647 | forward 8 648 | down 5 649 | down 2 650 | forward 6 651 | down 2 652 | down 3 653 | down 5 654 | up 6 655 | down 7 656 | forward 6 657 | forward 2 658 | down 8 659 | up 1 660 | up 1 661 | forward 2 662 | down 3 663 | forward 3 664 | down 8 665 | down 4 666 | forward 1 667 | down 2 668 | forward 6 669 | up 3 670 | forward 8 671 | down 6 672 | up 7 673 | forward 2 674 | forward 9 675 | forward 4 676 | forward 4 677 | up 7 678 | forward 6 679 | up 1 680 | forward 1 681 | forward 3 682 | down 4 683 | up 7 684 | forward 8 685 | forward 4 686 | down 8 687 | forward 4 688 | down 8 689 | forward 9 690 | down 3 691 | down 4 692 | up 6 693 | up 1 694 | forward 7 695 | up 3 696 | forward 5 697 | forward 4 698 | forward 5 699 | forward 7 700 | forward 1 701 | down 3 702 | up 5 703 | forward 7 704 | forward 4 705 | down 9 706 | down 6 707 | down 7 708 | up 3 709 | up 7 710 | up 8 711 | up 9 712 | down 4 713 | up 1 714 | forward 1 715 | up 3 716 | forward 6 717 | down 8 718 | forward 4 719 | down 7 720 | down 5 721 | down 4 722 | forward 7 723 | forward 5 724 | down 4 725 | down 7 726 | up 5 727 | down 2 728 | down 1 729 | down 8 730 | forward 7 731 | down 4 732 | forward 5 733 | up 9 734 | down 3 735 | up 2 736 | down 3 737 | forward 2 738 | forward 2 739 | forward 8 740 | down 2 741 | down 3 742 | forward 2 743 | down 6 744 | forward 9 745 | down 6 746 | down 1 747 | down 8 748 | down 3 749 | forward 4 750 | forward 4 751 | forward 4 752 | up 8 753 | forward 8 754 | up 4 755 | down 1 756 | forward 5 757 | down 9 758 | forward 7 759 | up 9 760 | up 3 761 | down 9 762 | down 8 763 | forward 3 764 | forward 4 765 | forward 5 766 | forward 4 767 | up 7 768 | down 2 769 | up 5 770 | forward 6 771 | down 3 772 | forward 6 773 | down 8 774 | down 3 775 | down 3 776 | down 4 777 | forward 8 778 | down 9 779 | down 2 780 | forward 2 781 | down 7 782 | forward 3 783 | up 2 784 | forward 4 785 | down 8 786 | forward 2 787 | forward 9 788 | forward 3 789 | down 6 790 | forward 9 791 | down 7 792 | forward 1 793 | forward 2 794 | forward 4 795 | forward 4 796 | up 4 797 | up 2 798 | down 7 799 | forward 9 800 | forward 9 801 | forward 7 802 | up 7 803 | down 2 804 | down 9 805 | forward 8 806 | down 5 807 | up 2 808 | down 6 809 | forward 9 810 | up 3 811 | down 5 812 | down 4 813 | forward 9 814 | forward 3 815 | down 6 816 | down 8 817 | up 5 818 | up 3 819 | down 2 820 | forward 9 821 | down 3 822 | forward 6 823 | down 9 824 | forward 5 825 | down 6 826 | up 6 827 | down 6 828 | forward 6 829 | forward 1 830 | down 3 831 | down 3 832 | up 8 833 | forward 1 834 | forward 4 835 | up 2 836 | forward 3 837 | forward 1 838 | forward 8 839 | forward 7 840 | down 7 841 | down 4 842 | down 6 843 | down 2 844 | forward 3 845 | down 2 846 | forward 6 847 | up 3 848 | down 9 849 | down 2 850 | forward 6 851 | down 6 852 | forward 5 853 | forward 2 854 | up 4 855 | forward 5 856 | up 5 857 | up 5 858 | up 3 859 | forward 9 860 | down 7 861 | forward 4 862 | down 7 863 | up 5 864 | down 3 865 | forward 5 866 | forward 3 867 | down 7 868 | up 2 869 | down 5 870 | forward 9 871 | forward 7 872 | up 7 873 | forward 5 874 | up 5 875 | down 1 876 | up 7 877 | forward 9 878 | down 8 879 | forward 2 880 | forward 8 881 | down 7 882 | down 3 883 | down 1 884 | up 7 885 | forward 4 886 | down 3 887 | forward 1 888 | forward 1 889 | forward 6 890 | up 7 891 | up 1 892 | forward 2 893 | down 8 894 | down 4 895 | down 2 896 | down 6 897 | forward 5 898 | down 7 899 | down 8 900 | down 7 901 | down 5 902 | down 5 903 | forward 1 904 | down 9 905 | forward 5 906 | down 6 907 | down 9 908 | up 3 909 | down 4 910 | forward 3 911 | down 6 912 | up 6 913 | forward 8 914 | forward 8 915 | forward 2 916 | down 2 917 | up 1 918 | forward 6 919 | forward 6 920 | up 9 921 | up 4 922 | forward 9 923 | up 7 924 | up 6 925 | down 2 926 | down 3 927 | up 7 928 | down 7 929 | forward 4 930 | forward 8 931 | down 3 932 | forward 1 933 | down 2 934 | forward 9 935 | forward 4 936 | forward 6 937 | down 7 938 | up 9 939 | forward 9 940 | forward 1 941 | forward 2 942 | down 1 943 | down 8 944 | down 7 945 | forward 3 946 | down 4 947 | down 9 948 | forward 2 949 | up 2 950 | forward 3 951 | up 3 952 | down 9 953 | down 2 954 | forward 3 955 | down 3 956 | forward 7 957 | forward 6 958 | down 6 959 | down 7 960 | forward 2 961 | down 9 962 | up 3 963 | down 6 964 | forward 3 965 | down 2 966 | down 1 967 | up 6 968 | down 3 969 | down 3 970 | down 1 971 | down 5 972 | down 3 973 | up 4 974 | down 2 975 | forward 5 976 | down 2 977 | down 8 978 | down 2 979 | down 5 980 | forward 9 981 | forward 4 982 | down 4 983 | down 2 984 | down 8 985 | forward 9 986 | down 8 987 | forward 1 988 | up 6 989 | forward 6 990 | down 7 991 | down 1 992 | down 2 993 | down 8 994 | down 8 995 | up 8 996 | forward 6 997 | forward 8 998 | forward 9 999 | forward 2 1000 | forward 5 1001 | -------------------------------------------------------------------------------- /day-2-2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | if err := run(); err != nil { 13 | fmt.Fprintln(os.Stderr, err) 14 | os.Exit(1) 15 | } 16 | } 17 | 18 | func run() error { 19 | input, err := ioutil.ReadAll(os.Stdin) 20 | if err != nil { 21 | return err 22 | } 23 | answer, err := Answer(strings.TrimSpace(string(input))) 24 | fmt.Printf("answer: %v\n", answer) 25 | return err 26 | } 27 | 28 | func Answer(input string) (int, error) { 29 | var aim, x, y int 30 | for _, line := range strings.Split(input, "\n") { 31 | parts := strings.Split(line, " ") 32 | if len(parts) != 2 { 33 | return 0, fmt.Errorf("bad line: %q", line) 34 | } 35 | amount, err := strconv.ParseInt(parts[1], 10, 64) 36 | if err != nil { 37 | return 0, fmt.Errorf("bad amount: %q: %s", parts, err) 38 | } 39 | switch parts[0] { 40 | case "forward": 41 | x += int(amount) 42 | y += aim * int(amount) 43 | case "down": 44 | aim += int(amount) 45 | case "up": 46 | aim -= int(amount) 47 | default: 48 | return 0, fmt.Errorf("bad command: %q", line) 49 | } 50 | } 51 | return x * y, nil 52 | } 53 | -------------------------------------------------------------------------------- /day-2-2/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/matryer/is" 8 | ) 9 | 10 | var testInput = strings.TrimSpace(` 11 | forward 5 12 | down 5 13 | forward 8 14 | up 3 15 | down 8 16 | forward 2 17 | `) 18 | 19 | func TestAnswer(t *testing.T) { 20 | is := is.New(t) 21 | answer, err := Answer(testInput) 22 | is.NoErr(err) 23 | is.Equal(answer, 900) 24 | } 25 | 26 | func BenchmarkAnswer(b *testing.B) { 27 | for i := 0; i < b.N; i++ { 28 | Answer(testInput) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /day-2-2/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-2-2/v1.cpu.pprof -------------------------------------------------------------------------------- /day-2-2/v1.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-2-2/v1.mem.pprof -------------------------------------------------------------------------------- /day-2-2/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-2-2 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 1820358 657.7 ns/op 6 | BenchmarkAnswer-6 1824421 655.4 ns/op 7 | BenchmarkAnswer-6 1812498 659.8 ns/op 8 | BenchmarkAnswer-6 1821037 657.6 ns/op 9 | BenchmarkAnswer-6 1805695 661.4 ns/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-2-2 9.458s 12 | -------------------------------------------------------------------------------- /day-3-1/input.txt: -------------------------------------------------------------------------------- 1 | 110001010111 2 | 011011110010 3 | 110011110011 4 | 101000010111 5 | 011101100100 6 | 111001011100 7 | 011100000101 8 | 011110110011 9 | 001001111111 10 | 111000010000 11 | 001000101100 12 | 011100111010 13 | 011100111000 14 | 011100010001 15 | 100001100000 16 | 111010111110 17 | 100011000101 18 | 010111000101 19 | 100110110011 20 | 101010110011 21 | 110101110010 22 | 110111100010 23 | 000001100100 24 | 010010011010 25 | 001001001100 26 | 101000000111 27 | 100100110011 28 | 111111100011 29 | 110010001010 30 | 100010110011 31 | 111101101001 32 | 101001001101 33 | 110111011101 34 | 100100101101 35 | 111111000011 36 | 001110010110 37 | 010110110010 38 | 010011100000 39 | 110011100011 40 | 111101001011 41 | 100001101000 42 | 100101100011 43 | 010101100110 44 | 101000001001 45 | 010001011100 46 | 111001010010 47 | 000110000110 48 | 110110111111 49 | 111111010000 50 | 110111110011 51 | 110110010010 52 | 000001001111 53 | 010001000111 54 | 101101100110 55 | 110011100100 56 | 101000010100 57 | 010100010000 58 | 100011001001 59 | 011000111101 60 | 000101011101 61 | 000110111110 62 | 011000101100 63 | 110101101001 64 | 100011110011 65 | 110101010001 66 | 100010100000 67 | 110010010001 68 | 000101101011 69 | 101100111011 70 | 111110110001 71 | 011001000100 72 | 001101111000 73 | 100100100101 74 | 101111001000 75 | 011010110110 76 | 001110011111 77 | 101011001001 78 | 110000100010 79 | 011110100110 80 | 001100101100 81 | 000110000001 82 | 011111001111 83 | 011000110010 84 | 001100011111 85 | 111100010100 86 | 010011111000 87 | 000100101010 88 | 101111100101 89 | 010000001100 90 | 100100101111 91 | 100011101100 92 | 000001111000 93 | 001110000011 94 | 011101011001 95 | 000001111101 96 | 000011001011 97 | 111111000110 98 | 000001011100 99 | 011001100000 100 | 111001011101 101 | 011010000011 102 | 101010101110 103 | 010110010101 104 | 000011101101 105 | 010010011000 106 | 000010100111 107 | 001000000111 108 | 111111011100 109 | 101010010000 110 | 101001001100 111 | 000000100111 112 | 101010101100 113 | 010110100111 114 | 001010001101 115 | 111000000101 116 | 111001101100 117 | 011110010001 118 | 011001111010 119 | 010010011011 120 | 011110111000 121 | 010111110000 122 | 001110001011 123 | 010001001011 124 | 011001001010 125 | 011001001101 126 | 001101011101 127 | 100110100000 128 | 100001111110 129 | 101110100011 130 | 100010111111 131 | 001010010011 132 | 000010011001 133 | 011001111101 134 | 000100000010 135 | 100110010011 136 | 001111001000 137 | 110001011101 138 | 000100011000 139 | 111110000000 140 | 111001101000 141 | 100111000100 142 | 010000010100 143 | 011000110111 144 | 000110001101 145 | 101100110010 146 | 011111101001 147 | 000000100010 148 | 000001101000 149 | 111001111101 150 | 111100010111 151 | 110000010101 152 | 110000101100 153 | 101111010011 154 | 000100010101 155 | 100111100011 156 | 110100101111 157 | 101000001000 158 | 001000100000 159 | 100111111010 160 | 001101111101 161 | 000000101000 162 | 100111101100 163 | 100111010100 164 | 111100010110 165 | 100001010011 166 | 010010001000 167 | 111101010101 168 | 101110101010 169 | 111110001110 170 | 001010111010 171 | 100110001000 172 | 101111001111 173 | 110010011101 174 | 110001110101 175 | 011101000000 176 | 010011110110 177 | 001110101001 178 | 011110011010 179 | 110010111100 180 | 010000100001 181 | 010010000100 182 | 111111000101 183 | 010111100111 184 | 101010110010 185 | 100010010011 186 | 101011010000 187 | 000101100000 188 | 011001000011 189 | 010110000000 190 | 101011101111 191 | 001101001110 192 | 001100100110 193 | 011111110011 194 | 010000101101 195 | 000111101101 196 | 111100101101 197 | 000011001101 198 | 110011111100 199 | 011000110000 200 | 000001010010 201 | 111100111111 202 | 001010000100 203 | 000011010010 204 | 010001000001 205 | 111010111000 206 | 110001010011 207 | 000000101011 208 | 011110011011 209 | 100110111000 210 | 010010110010 211 | 000010111110 212 | 110010001001 213 | 000111001001 214 | 001000011100 215 | 111111011010 216 | 000000110101 217 | 111011111011 218 | 100001110111 219 | 010001110000 220 | 010101100100 221 | 011010100001 222 | 111000101101 223 | 001100110110 224 | 010001111110 225 | 100000101011 226 | 011111111001 227 | 111000001100 228 | 011111100011 229 | 110110110000 230 | 011000101010 231 | 101000000011 232 | 101111110100 233 | 011000101101 234 | 001000011010 235 | 101001100111 236 | 101100001101 237 | 100100101100 238 | 001101011001 239 | 001111100111 240 | 011100101001 241 | 110010000000 242 | 010100111000 243 | 000011010111 244 | 000000100110 245 | 101001000000 246 | 000110100100 247 | 110001110011 248 | 001011001101 249 | 100000111100 250 | 101011011111 251 | 000010110110 252 | 010101110100 253 | 111100111001 254 | 111010101101 255 | 101100001001 256 | 011111000111 257 | 010001101000 258 | 100000001111 259 | 011111101100 260 | 011111100111 261 | 111101111110 262 | 110110100101 263 | 011110001011 264 | 100111100001 265 | 000001101101 266 | 100110101110 267 | 100000010011 268 | 110000000001 269 | 001001101001 270 | 000001111111 271 | 111001001010 272 | 101011100101 273 | 100100000000 274 | 110001101011 275 | 011111001011 276 | 010010001011 277 | 000101010011 278 | 110010110100 279 | 101010101011 280 | 100100001100 281 | 000001100011 282 | 101010000010 283 | 111101100100 284 | 001011010111 285 | 000001010001 286 | 001010001011 287 | 100110000011 288 | 000010101010 289 | 110111011100 290 | 001100111000 291 | 111011010111 292 | 100100110000 293 | 000010111010 294 | 000011010001 295 | 100001111111 296 | 111111000100 297 | 010111111000 298 | 100101010010 299 | 001111111010 300 | 001111011100 301 | 111101100111 302 | 111011011011 303 | 111000100110 304 | 011101001011 305 | 010100101010 306 | 010100001111 307 | 010000001111 308 | 000000000010 309 | 010011010111 310 | 001101001011 311 | 101011001011 312 | 011001101101 313 | 100000000111 314 | 100110011010 315 | 000101000110 316 | 101100010011 317 | 101011011100 318 | 001101010100 319 | 110101110111 320 | 001100001000 321 | 001001100100 322 | 111101011010 323 | 001100100100 324 | 100000100010 325 | 001110111001 326 | 101101001110 327 | 001101110111 328 | 010101100101 329 | 000011111110 330 | 001000111101 331 | 110011101011 332 | 110101011000 333 | 000000100101 334 | 100110100001 335 | 111111101101 336 | 010100101111 337 | 110101011010 338 | 011010011100 339 | 101101010001 340 | 101001010011 341 | 011111001100 342 | 101001010111 343 | 011100100011 344 | 101011110000 345 | 010111001010 346 | 111011000111 347 | 100111001101 348 | 001110111010 349 | 100001111000 350 | 111011010011 351 | 110000101010 352 | 011010000000 353 | 110001111010 354 | 100101000100 355 | 010000110100 356 | 101000101010 357 | 011010101110 358 | 010000111100 359 | 101011100100 360 | 101101111010 361 | 111011111110 362 | 000101010111 363 | 000010111000 364 | 011101101010 365 | 101110100110 366 | 010000011010 367 | 101100100000 368 | 010011010101 369 | 101100011100 370 | 011010101010 371 | 010111101010 372 | 111011100111 373 | 111111110010 374 | 101101100100 375 | 111001010100 376 | 011000001110 377 | 110110001110 378 | 111110100110 379 | 001011011100 380 | 101000010010 381 | 100000101010 382 | 010000011110 383 | 001001110111 384 | 001001001011 385 | 110010011110 386 | 001111001100 387 | 110110100010 388 | 111100000111 389 | 010101101011 390 | 001111111001 391 | 101011000000 392 | 011100011000 393 | 000001000000 394 | 100101001100 395 | 110010011001 396 | 111100111110 397 | 010000110110 398 | 110000111000 399 | 110111100001 400 | 000100100010 401 | 100010001110 402 | 010000111101 403 | 111100011000 404 | 110000000101 405 | 000000000001 406 | 010011111100 407 | 011011111101 408 | 111001111010 409 | 001001001001 410 | 010101011010 411 | 011010011111 412 | 001111000011 413 | 101111111111 414 | 000111101000 415 | 011000111110 416 | 001100101101 417 | 101000000110 418 | 000100001010 419 | 111110010101 420 | 000011101000 421 | 011010101000 422 | 100111100000 423 | 111001111111 424 | 010101000111 425 | 011000100101 426 | 001001110001 427 | 101101011011 428 | 001000001100 429 | 111110111010 430 | 011110111010 431 | 111101100001 432 | 011111101000 433 | 110100010100 434 | 010001110011 435 | 000011010011 436 | 010000110010 437 | 000011111011 438 | 101111011000 439 | 010101111110 440 | 100100101011 441 | 001000011011 442 | 011000100000 443 | 100100111101 444 | 001010110011 445 | 000000000000 446 | 000110111011 447 | 001001011001 448 | 011101010010 449 | 000111000011 450 | 010001000100 451 | 011110011111 452 | 010010111011 453 | 100000000011 454 | 001100111101 455 | 000001000110 456 | 000010000010 457 | 101111001010 458 | 000111000001 459 | 100101011100 460 | 111001110100 461 | 100111001111 462 | 011110111111 463 | 010101011110 464 | 101010011011 465 | 101000010101 466 | 101001101000 467 | 001001011101 468 | 010110101100 469 | 101110111100 470 | 000111011110 471 | 010111001101 472 | 001101100010 473 | 011101001111 474 | 100111111111 475 | 000110101110 476 | 011110001110 477 | 110011100111 478 | 010011100101 479 | 100101000011 480 | 100101010011 481 | 111000110110 482 | 110111011111 483 | 000100011110 484 | 100000000001 485 | 010111111111 486 | 100000100011 487 | 110010011111 488 | 111101110110 489 | 001000001001 490 | 001100011001 491 | 111100110001 492 | 100110100101 493 | 010111101000 494 | 000000000110 495 | 000011011001 496 | 100100001111 497 | 001111100100 498 | 001011010011 499 | 001000110011 500 | 110100010010 501 | 011100110111 502 | 011010110010 503 | 011001110110 504 | 011011100010 505 | 001110101011 506 | 101101100111 507 | 101101111100 508 | 000110000101 509 | 000001110010 510 | 001101110010 511 | 101011000100 512 | 000110000000 513 | 001001011111 514 | 100101101011 515 | 001010100001 516 | 110000111110 517 | 011111101111 518 | 110110111100 519 | 001000010110 520 | 000101111110 521 | 111001000001 522 | 000100110011 523 | 110110000101 524 | 101100101011 525 | 101110000010 526 | 011101100001 527 | 010011000001 528 | 010111000011 529 | 010111011101 530 | 101010100001 531 | 000111011011 532 | 101110010000 533 | 110000000010 534 | 101100011101 535 | 011000011000 536 | 001111101101 537 | 101000001010 538 | 101011010001 539 | 011111100001 540 | 101001011110 541 | 100101011000 542 | 011110001100 543 | 111100011110 544 | 010011101110 545 | 001001110000 546 | 001001000011 547 | 100001010000 548 | 000110010000 549 | 110111010111 550 | 000100110101 551 | 001110101000 552 | 101011000011 553 | 001011100000 554 | 111111111111 555 | 111111011110 556 | 110001100001 557 | 001000001111 558 | 101000100100 559 | 001011001001 560 | 110110001101 561 | 000100000000 562 | 011100001101 563 | 110011001000 564 | 001111011101 565 | 010000111111 566 | 010110011110 567 | 011110111011 568 | 101111011101 569 | 001100011000 570 | 001011111001 571 | 000110001011 572 | 011011010100 573 | 111110001011 574 | 010000110111 575 | 001100011101 576 | 011110111001 577 | 000010101001 578 | 001110000001 579 | 011111010101 580 | 000010010100 581 | 000101011001 582 | 100100000001 583 | 001111101011 584 | 111110010011 585 | 000111111011 586 | 001101010110 587 | 001100111001 588 | 000100011101 589 | 111010010111 590 | 000100000001 591 | 001011101111 592 | 101001110011 593 | 001011110101 594 | 011000001101 595 | 110011001011 596 | 011110111100 597 | 110110101000 598 | 011010001101 599 | 110111001000 600 | 110010010101 601 | 011010001011 602 | 000011100111 603 | 011000110001 604 | 001100001111 605 | 110010011010 606 | 101100101100 607 | 001100000110 608 | 010101001111 609 | 000011000100 610 | 110001000111 611 | 001001011000 612 | 001001001000 613 | 000010111101 614 | 100101001010 615 | 011100111100 616 | 101000011011 617 | 101011010111 618 | 111001000011 619 | 100100100110 620 | 011001011011 621 | 000011110011 622 | 001101000111 623 | 011010010100 624 | 101010101000 625 | 100010110000 626 | 100001011110 627 | 100000110110 628 | 001011101001 629 | 000110100011 630 | 111000101010 631 | 111001011001 632 | 101111010010 633 | 011100101010 634 | 100010111000 635 | 010100101110 636 | 011001110000 637 | 000010001101 638 | 101110000111 639 | 011011001111 640 | 011110001000 641 | 010010100011 642 | 110001100010 643 | 001101011011 644 | 110100000101 645 | 101110100111 646 | 001110111011 647 | 000110100101 648 | 100100100001 649 | 101000111100 650 | 100011101110 651 | 110010000101 652 | 101100011001 653 | 100000010111 654 | 011100100101 655 | 000010011011 656 | 001011001100 657 | 011001000000 658 | 000101000101 659 | 100001001100 660 | 000001101010 661 | 110111101100 662 | 111001101010 663 | 110000110111 664 | 000110010001 665 | 011100000000 666 | 010000111010 667 | 000101000000 668 | 010000101010 669 | 010011110001 670 | 101011010101 671 | 100000110111 672 | 101001110010 673 | 100011011100 674 | 010011100011 675 | 100000100111 676 | 110100110000 677 | 000100001011 678 | 101101011000 679 | 010110011001 680 | 010110111111 681 | 101110010101 682 | 011110001101 683 | 110001001000 684 | 001001101100 685 | 100111010011 686 | 001100010011 687 | 110101111001 688 | 100010101011 689 | 111010001110 690 | 110001100111 691 | 111000010010 692 | 001000001011 693 | 111001000010 694 | 100100100100 695 | 110010101001 696 | 111101101010 697 | 111111100101 698 | 100010010001 699 | 001010010110 700 | 111101011000 701 | 001010111100 702 | 001001111110 703 | 100010100110 704 | 100001110100 705 | 001111001101 706 | 101100100111 707 | 101101100101 708 | 100101110111 709 | 000111110111 710 | 000111001000 711 | 010101000010 712 | 011000111100 713 | 001001001110 714 | 111101010001 715 | 001011010101 716 | 100011000111 717 | 100000001001 718 | 011100011110 719 | 010111011011 720 | 011000010011 721 | 101101011110 722 | 000000100011 723 | 111110010010 724 | 111010011101 725 | 001000100100 726 | 110101100001 727 | 100101101000 728 | 001110111111 729 | 010001000101 730 | 111110000101 731 | 101000001101 732 | 110101010000 733 | 111110101110 734 | 011111011000 735 | 001001001111 736 | 000101010110 737 | 001100110000 738 | 001111101000 739 | 101000100101 740 | 010000000010 741 | 110011000010 742 | 000000001100 743 | 010000101011 744 | 010101011011 745 | 101011010100 746 | 010001011011 747 | 111100011001 748 | 100000111110 749 | 110001101010 750 | 100111101001 751 | 100110001110 752 | 110001010101 753 | 101100001000 754 | 100001000010 755 | 000110100001 756 | 001010000000 757 | 011111100000 758 | 111110101111 759 | 000001101001 760 | 000000111110 761 | 101111101001 762 | 001010000010 763 | 011110010010 764 | 101111000111 765 | 111110101010 766 | 000100001000 767 | 000111000000 768 | 110010010110 769 | 000001111110 770 | 010110101010 771 | 001010100011 772 | 001111011001 773 | 111001001111 774 | 100100010111 775 | 101100001011 776 | 100111000110 777 | 111010111101 778 | 010001011110 779 | 101110000011 780 | 010111000010 781 | 110110001011 782 | 111010100011 783 | 111100011101 784 | 101101101001 785 | 110100001000 786 | 110001011001 787 | 110010100001 788 | 111110010110 789 | 010100100011 790 | 001000011101 791 | 001011001010 792 | 011100111011 793 | 001111100110 794 | 001101100110 795 | 001011000001 796 | 010100100110 797 | 100100100111 798 | 010100011011 799 | 000101110001 800 | 010110011111 801 | 000001011101 802 | 110101011001 803 | 001101101010 804 | 011111111010 805 | 111001100011 806 | 100001000111 807 | 110110011111 808 | 100101010001 809 | 011100100010 810 | 100100011000 811 | 101111001011 812 | 111001011000 813 | 110000101110 814 | 010100100101 815 | 110011101000 816 | 001101000011 817 | 111101100101 818 | 011010011011 819 | 100110001101 820 | 111001111100 821 | 001000100010 822 | 000101111101 823 | 101110011000 824 | 001011111010 825 | 111100101001 826 | 011000101001 827 | 001111010111 828 | 001100110010 829 | 011000011011 830 | 110111011000 831 | 100100000110 832 | 011010110000 833 | 110111101111 834 | 111000111101 835 | 111111100110 836 | 000101010010 837 | 010101001010 838 | 110100110101 839 | 011011100101 840 | 110110111011 841 | 100010111110 842 | 100110111010 843 | 100011001010 844 | 100100100000 845 | 101000110110 846 | 001010101010 847 | 011001101111 848 | 001110110000 849 | 010001100100 850 | 011000100100 851 | 001011001011 852 | 110111100110 853 | 010110010111 854 | 001011011010 855 | 111100001010 856 | 000010001100 857 | 011010001111 858 | 100100001101 859 | 100010011100 860 | 000010001000 861 | 101001010000 862 | 110101001101 863 | 010110111100 864 | 101001100100 865 | 100000111010 866 | 010000010001 867 | 011101011101 868 | 100011110010 869 | 100100011111 870 | 100011100101 871 | 001010010010 872 | 000110011111 873 | 010000000111 874 | 111001101101 875 | 010011000010 876 | 000001111010 877 | 010010001111 878 | 101011100001 879 | 101100111100 880 | 100001000000 881 | 110111110010 882 | 100110000111 883 | 100000111011 884 | 111010011110 885 | 011011011011 886 | 101011000110 887 | 011100011001 888 | 000101011100 889 | 010000101111 890 | 100010100001 891 | 111000100101 892 | 011010010001 893 | 110110100011 894 | 100000011100 895 | 101110101101 896 | 000010110100 897 | 101011111110 898 | 001000100111 899 | 101001001010 900 | 001111110101 901 | 001001000010 902 | 001100101110 903 | 111000001000 904 | 000000100000 905 | 000100111110 906 | 111111110100 907 | 110101001100 908 | 001100000010 909 | 100011011001 910 | 000110000010 911 | 100010101101 912 | 111110101011 913 | 110100000000 914 | 000100111001 915 | 001111001011 916 | 110111011011 917 | 001111100010 918 | 101111011010 919 | 111010011011 920 | 100111101010 921 | 011011011001 922 | 010100000011 923 | 001111010001 924 | 101010101101 925 | 110000011111 926 | 001111111111 927 | 000110000100 928 | 101111101010 929 | 101011011101 930 | 010001011010 931 | 001001011011 932 | 101011010010 933 | 111010000010 934 | 011100101000 935 | 101001011010 936 | 000111110101 937 | 110011011101 938 | 101010010011 939 | 101100001111 940 | 111001010001 941 | 100100010110 942 | 010100100001 943 | 011110110101 944 | 110100000111 945 | 110101001000 946 | 101000010000 947 | 110000000011 948 | 011111110110 949 | 100001010100 950 | 011111000101 951 | 010010101001 952 | 000111100100 953 | 001010000110 954 | 100100110110 955 | 110010101101 956 | 010001111101 957 | 101100000000 958 | 001100000000 959 | 011111111110 960 | 110001100101 961 | 000111001100 962 | 011101111110 963 | 000100110000 964 | 111111111000 965 | 101110010001 966 | 100111000010 967 | 100111011110 968 | 000100111010 969 | 110101011011 970 | 001000111110 971 | 101101110110 972 | 110110010011 973 | 011010100101 974 | 001010101111 975 | 100110111001 976 | 010001111100 977 | 010110101000 978 | 011000000000 979 | 010001011111 980 | 010101101111 981 | 111001010110 982 | 100001001011 983 | 110000100111 984 | 011100000001 985 | 110101100000 986 | 110010110010 987 | 111010111001 988 | 011010111000 989 | 101100000110 990 | 010100011111 991 | 001010111000 992 | 101100101101 993 | 011000111010 994 | 000001001100 995 | 001111010010 996 | 011010100000 997 | 110100110111 998 | 101101000100 999 | 001110001101 1000 | 111001101111 1001 | -------------------------------------------------------------------------------- /day-3-1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | if err := run(); err != nil { 12 | fmt.Fprintln(os.Stderr, err) 13 | os.Exit(1) 14 | } 15 | } 16 | 17 | func run() error { 18 | input, err := ioutil.ReadAll(os.Stdin) 19 | if err != nil { 20 | return err 21 | } 22 | answer, err := Answer(strings.TrimSpace(string(input))) 23 | fmt.Printf("answer: %v\n", answer) 24 | return err 25 | } 26 | 27 | // See v*.go files for Answer() implementations. 28 | -------------------------------------------------------------------------------- /day-3-1/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/matryer/is" 8 | ) 9 | 10 | var testInput = strings.TrimSpace(` 11 | 00100 12 | 11110 13 | 10110 14 | 10111 15 | 10101 16 | 01111 17 | 00111 18 | 11100 19 | 10000 20 | 11001 21 | 00010 22 | 01010 23 | `) 24 | 25 | func TestAnswer(t *testing.T) { 26 | is := is.New(t) 27 | answer, err := Answer(testInput) 28 | is.NoErr(err) 29 | is.Equal(answer, 198) 30 | } 31 | 32 | func BenchmarkAnswer(b *testing.B) { 33 | for i := 0; i < b.N; i++ { 34 | Answer(testInput) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /day-3-1/v1.go: -------------------------------------------------------------------------------- 1 | //go:build v1 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func Answer(input string) (int, error) { 8 | var ( 9 | col = 0 10 | counts []int 11 | lines = 0 12 | ) 13 | for i := 0; i < len(input); i++ { 14 | c := input[i] 15 | switch c { 16 | case '0': 17 | if col >= len(counts) { 18 | counts = append(counts, 0) 19 | } 20 | col++ 21 | case '1': 22 | if col >= len(counts) { 23 | counts = append(counts, 1) 24 | } else { 25 | counts[col]++ 26 | } 27 | col++ 28 | case '\n': 29 | col = 0 30 | lines++ 31 | default: 32 | return 0, fmt.Errorf("bad char: %q", string(c)) 33 | } 34 | } 35 | 36 | var gamma, epsilon int 37 | for i, v := range counts { 38 | if v > lines/2 { 39 | gamma = gamma | (1 << (len(counts) - i - 1)) 40 | } else { 41 | epsilon = epsilon | (1 << (len(counts) - i - 1)) 42 | } 43 | } 44 | return gamma * epsilon, nil 45 | } 46 | -------------------------------------------------------------------------------- /day-3-2/input.txt: -------------------------------------------------------------------------------- 1 | 110001010111 2 | 011011110010 3 | 110011110011 4 | 101000010111 5 | 011101100100 6 | 111001011100 7 | 011100000101 8 | 011110110011 9 | 001001111111 10 | 111000010000 11 | 001000101100 12 | 011100111010 13 | 011100111000 14 | 011100010001 15 | 100001100000 16 | 111010111110 17 | 100011000101 18 | 010111000101 19 | 100110110011 20 | 101010110011 21 | 110101110010 22 | 110111100010 23 | 000001100100 24 | 010010011010 25 | 001001001100 26 | 101000000111 27 | 100100110011 28 | 111111100011 29 | 110010001010 30 | 100010110011 31 | 111101101001 32 | 101001001101 33 | 110111011101 34 | 100100101101 35 | 111111000011 36 | 001110010110 37 | 010110110010 38 | 010011100000 39 | 110011100011 40 | 111101001011 41 | 100001101000 42 | 100101100011 43 | 010101100110 44 | 101000001001 45 | 010001011100 46 | 111001010010 47 | 000110000110 48 | 110110111111 49 | 111111010000 50 | 110111110011 51 | 110110010010 52 | 000001001111 53 | 010001000111 54 | 101101100110 55 | 110011100100 56 | 101000010100 57 | 010100010000 58 | 100011001001 59 | 011000111101 60 | 000101011101 61 | 000110111110 62 | 011000101100 63 | 110101101001 64 | 100011110011 65 | 110101010001 66 | 100010100000 67 | 110010010001 68 | 000101101011 69 | 101100111011 70 | 111110110001 71 | 011001000100 72 | 001101111000 73 | 100100100101 74 | 101111001000 75 | 011010110110 76 | 001110011111 77 | 101011001001 78 | 110000100010 79 | 011110100110 80 | 001100101100 81 | 000110000001 82 | 011111001111 83 | 011000110010 84 | 001100011111 85 | 111100010100 86 | 010011111000 87 | 000100101010 88 | 101111100101 89 | 010000001100 90 | 100100101111 91 | 100011101100 92 | 000001111000 93 | 001110000011 94 | 011101011001 95 | 000001111101 96 | 000011001011 97 | 111111000110 98 | 000001011100 99 | 011001100000 100 | 111001011101 101 | 011010000011 102 | 101010101110 103 | 010110010101 104 | 000011101101 105 | 010010011000 106 | 000010100111 107 | 001000000111 108 | 111111011100 109 | 101010010000 110 | 101001001100 111 | 000000100111 112 | 101010101100 113 | 010110100111 114 | 001010001101 115 | 111000000101 116 | 111001101100 117 | 011110010001 118 | 011001111010 119 | 010010011011 120 | 011110111000 121 | 010111110000 122 | 001110001011 123 | 010001001011 124 | 011001001010 125 | 011001001101 126 | 001101011101 127 | 100110100000 128 | 100001111110 129 | 101110100011 130 | 100010111111 131 | 001010010011 132 | 000010011001 133 | 011001111101 134 | 000100000010 135 | 100110010011 136 | 001111001000 137 | 110001011101 138 | 000100011000 139 | 111110000000 140 | 111001101000 141 | 100111000100 142 | 010000010100 143 | 011000110111 144 | 000110001101 145 | 101100110010 146 | 011111101001 147 | 000000100010 148 | 000001101000 149 | 111001111101 150 | 111100010111 151 | 110000010101 152 | 110000101100 153 | 101111010011 154 | 000100010101 155 | 100111100011 156 | 110100101111 157 | 101000001000 158 | 001000100000 159 | 100111111010 160 | 001101111101 161 | 000000101000 162 | 100111101100 163 | 100111010100 164 | 111100010110 165 | 100001010011 166 | 010010001000 167 | 111101010101 168 | 101110101010 169 | 111110001110 170 | 001010111010 171 | 100110001000 172 | 101111001111 173 | 110010011101 174 | 110001110101 175 | 011101000000 176 | 010011110110 177 | 001110101001 178 | 011110011010 179 | 110010111100 180 | 010000100001 181 | 010010000100 182 | 111111000101 183 | 010111100111 184 | 101010110010 185 | 100010010011 186 | 101011010000 187 | 000101100000 188 | 011001000011 189 | 010110000000 190 | 101011101111 191 | 001101001110 192 | 001100100110 193 | 011111110011 194 | 010000101101 195 | 000111101101 196 | 111100101101 197 | 000011001101 198 | 110011111100 199 | 011000110000 200 | 000001010010 201 | 111100111111 202 | 001010000100 203 | 000011010010 204 | 010001000001 205 | 111010111000 206 | 110001010011 207 | 000000101011 208 | 011110011011 209 | 100110111000 210 | 010010110010 211 | 000010111110 212 | 110010001001 213 | 000111001001 214 | 001000011100 215 | 111111011010 216 | 000000110101 217 | 111011111011 218 | 100001110111 219 | 010001110000 220 | 010101100100 221 | 011010100001 222 | 111000101101 223 | 001100110110 224 | 010001111110 225 | 100000101011 226 | 011111111001 227 | 111000001100 228 | 011111100011 229 | 110110110000 230 | 011000101010 231 | 101000000011 232 | 101111110100 233 | 011000101101 234 | 001000011010 235 | 101001100111 236 | 101100001101 237 | 100100101100 238 | 001101011001 239 | 001111100111 240 | 011100101001 241 | 110010000000 242 | 010100111000 243 | 000011010111 244 | 000000100110 245 | 101001000000 246 | 000110100100 247 | 110001110011 248 | 001011001101 249 | 100000111100 250 | 101011011111 251 | 000010110110 252 | 010101110100 253 | 111100111001 254 | 111010101101 255 | 101100001001 256 | 011111000111 257 | 010001101000 258 | 100000001111 259 | 011111101100 260 | 011111100111 261 | 111101111110 262 | 110110100101 263 | 011110001011 264 | 100111100001 265 | 000001101101 266 | 100110101110 267 | 100000010011 268 | 110000000001 269 | 001001101001 270 | 000001111111 271 | 111001001010 272 | 101011100101 273 | 100100000000 274 | 110001101011 275 | 011111001011 276 | 010010001011 277 | 000101010011 278 | 110010110100 279 | 101010101011 280 | 100100001100 281 | 000001100011 282 | 101010000010 283 | 111101100100 284 | 001011010111 285 | 000001010001 286 | 001010001011 287 | 100110000011 288 | 000010101010 289 | 110111011100 290 | 001100111000 291 | 111011010111 292 | 100100110000 293 | 000010111010 294 | 000011010001 295 | 100001111111 296 | 111111000100 297 | 010111111000 298 | 100101010010 299 | 001111111010 300 | 001111011100 301 | 111101100111 302 | 111011011011 303 | 111000100110 304 | 011101001011 305 | 010100101010 306 | 010100001111 307 | 010000001111 308 | 000000000010 309 | 010011010111 310 | 001101001011 311 | 101011001011 312 | 011001101101 313 | 100000000111 314 | 100110011010 315 | 000101000110 316 | 101100010011 317 | 101011011100 318 | 001101010100 319 | 110101110111 320 | 001100001000 321 | 001001100100 322 | 111101011010 323 | 001100100100 324 | 100000100010 325 | 001110111001 326 | 101101001110 327 | 001101110111 328 | 010101100101 329 | 000011111110 330 | 001000111101 331 | 110011101011 332 | 110101011000 333 | 000000100101 334 | 100110100001 335 | 111111101101 336 | 010100101111 337 | 110101011010 338 | 011010011100 339 | 101101010001 340 | 101001010011 341 | 011111001100 342 | 101001010111 343 | 011100100011 344 | 101011110000 345 | 010111001010 346 | 111011000111 347 | 100111001101 348 | 001110111010 349 | 100001111000 350 | 111011010011 351 | 110000101010 352 | 011010000000 353 | 110001111010 354 | 100101000100 355 | 010000110100 356 | 101000101010 357 | 011010101110 358 | 010000111100 359 | 101011100100 360 | 101101111010 361 | 111011111110 362 | 000101010111 363 | 000010111000 364 | 011101101010 365 | 101110100110 366 | 010000011010 367 | 101100100000 368 | 010011010101 369 | 101100011100 370 | 011010101010 371 | 010111101010 372 | 111011100111 373 | 111111110010 374 | 101101100100 375 | 111001010100 376 | 011000001110 377 | 110110001110 378 | 111110100110 379 | 001011011100 380 | 101000010010 381 | 100000101010 382 | 010000011110 383 | 001001110111 384 | 001001001011 385 | 110010011110 386 | 001111001100 387 | 110110100010 388 | 111100000111 389 | 010101101011 390 | 001111111001 391 | 101011000000 392 | 011100011000 393 | 000001000000 394 | 100101001100 395 | 110010011001 396 | 111100111110 397 | 010000110110 398 | 110000111000 399 | 110111100001 400 | 000100100010 401 | 100010001110 402 | 010000111101 403 | 111100011000 404 | 110000000101 405 | 000000000001 406 | 010011111100 407 | 011011111101 408 | 111001111010 409 | 001001001001 410 | 010101011010 411 | 011010011111 412 | 001111000011 413 | 101111111111 414 | 000111101000 415 | 011000111110 416 | 001100101101 417 | 101000000110 418 | 000100001010 419 | 111110010101 420 | 000011101000 421 | 011010101000 422 | 100111100000 423 | 111001111111 424 | 010101000111 425 | 011000100101 426 | 001001110001 427 | 101101011011 428 | 001000001100 429 | 111110111010 430 | 011110111010 431 | 111101100001 432 | 011111101000 433 | 110100010100 434 | 010001110011 435 | 000011010011 436 | 010000110010 437 | 000011111011 438 | 101111011000 439 | 010101111110 440 | 100100101011 441 | 001000011011 442 | 011000100000 443 | 100100111101 444 | 001010110011 445 | 000000000000 446 | 000110111011 447 | 001001011001 448 | 011101010010 449 | 000111000011 450 | 010001000100 451 | 011110011111 452 | 010010111011 453 | 100000000011 454 | 001100111101 455 | 000001000110 456 | 000010000010 457 | 101111001010 458 | 000111000001 459 | 100101011100 460 | 111001110100 461 | 100111001111 462 | 011110111111 463 | 010101011110 464 | 101010011011 465 | 101000010101 466 | 101001101000 467 | 001001011101 468 | 010110101100 469 | 101110111100 470 | 000111011110 471 | 010111001101 472 | 001101100010 473 | 011101001111 474 | 100111111111 475 | 000110101110 476 | 011110001110 477 | 110011100111 478 | 010011100101 479 | 100101000011 480 | 100101010011 481 | 111000110110 482 | 110111011111 483 | 000100011110 484 | 100000000001 485 | 010111111111 486 | 100000100011 487 | 110010011111 488 | 111101110110 489 | 001000001001 490 | 001100011001 491 | 111100110001 492 | 100110100101 493 | 010111101000 494 | 000000000110 495 | 000011011001 496 | 100100001111 497 | 001111100100 498 | 001011010011 499 | 001000110011 500 | 110100010010 501 | 011100110111 502 | 011010110010 503 | 011001110110 504 | 011011100010 505 | 001110101011 506 | 101101100111 507 | 101101111100 508 | 000110000101 509 | 000001110010 510 | 001101110010 511 | 101011000100 512 | 000110000000 513 | 001001011111 514 | 100101101011 515 | 001010100001 516 | 110000111110 517 | 011111101111 518 | 110110111100 519 | 001000010110 520 | 000101111110 521 | 111001000001 522 | 000100110011 523 | 110110000101 524 | 101100101011 525 | 101110000010 526 | 011101100001 527 | 010011000001 528 | 010111000011 529 | 010111011101 530 | 101010100001 531 | 000111011011 532 | 101110010000 533 | 110000000010 534 | 101100011101 535 | 011000011000 536 | 001111101101 537 | 101000001010 538 | 101011010001 539 | 011111100001 540 | 101001011110 541 | 100101011000 542 | 011110001100 543 | 111100011110 544 | 010011101110 545 | 001001110000 546 | 001001000011 547 | 100001010000 548 | 000110010000 549 | 110111010111 550 | 000100110101 551 | 001110101000 552 | 101011000011 553 | 001011100000 554 | 111111111111 555 | 111111011110 556 | 110001100001 557 | 001000001111 558 | 101000100100 559 | 001011001001 560 | 110110001101 561 | 000100000000 562 | 011100001101 563 | 110011001000 564 | 001111011101 565 | 010000111111 566 | 010110011110 567 | 011110111011 568 | 101111011101 569 | 001100011000 570 | 001011111001 571 | 000110001011 572 | 011011010100 573 | 111110001011 574 | 010000110111 575 | 001100011101 576 | 011110111001 577 | 000010101001 578 | 001110000001 579 | 011111010101 580 | 000010010100 581 | 000101011001 582 | 100100000001 583 | 001111101011 584 | 111110010011 585 | 000111111011 586 | 001101010110 587 | 001100111001 588 | 000100011101 589 | 111010010111 590 | 000100000001 591 | 001011101111 592 | 101001110011 593 | 001011110101 594 | 011000001101 595 | 110011001011 596 | 011110111100 597 | 110110101000 598 | 011010001101 599 | 110111001000 600 | 110010010101 601 | 011010001011 602 | 000011100111 603 | 011000110001 604 | 001100001111 605 | 110010011010 606 | 101100101100 607 | 001100000110 608 | 010101001111 609 | 000011000100 610 | 110001000111 611 | 001001011000 612 | 001001001000 613 | 000010111101 614 | 100101001010 615 | 011100111100 616 | 101000011011 617 | 101011010111 618 | 111001000011 619 | 100100100110 620 | 011001011011 621 | 000011110011 622 | 001101000111 623 | 011010010100 624 | 101010101000 625 | 100010110000 626 | 100001011110 627 | 100000110110 628 | 001011101001 629 | 000110100011 630 | 111000101010 631 | 111001011001 632 | 101111010010 633 | 011100101010 634 | 100010111000 635 | 010100101110 636 | 011001110000 637 | 000010001101 638 | 101110000111 639 | 011011001111 640 | 011110001000 641 | 010010100011 642 | 110001100010 643 | 001101011011 644 | 110100000101 645 | 101110100111 646 | 001110111011 647 | 000110100101 648 | 100100100001 649 | 101000111100 650 | 100011101110 651 | 110010000101 652 | 101100011001 653 | 100000010111 654 | 011100100101 655 | 000010011011 656 | 001011001100 657 | 011001000000 658 | 000101000101 659 | 100001001100 660 | 000001101010 661 | 110111101100 662 | 111001101010 663 | 110000110111 664 | 000110010001 665 | 011100000000 666 | 010000111010 667 | 000101000000 668 | 010000101010 669 | 010011110001 670 | 101011010101 671 | 100000110111 672 | 101001110010 673 | 100011011100 674 | 010011100011 675 | 100000100111 676 | 110100110000 677 | 000100001011 678 | 101101011000 679 | 010110011001 680 | 010110111111 681 | 101110010101 682 | 011110001101 683 | 110001001000 684 | 001001101100 685 | 100111010011 686 | 001100010011 687 | 110101111001 688 | 100010101011 689 | 111010001110 690 | 110001100111 691 | 111000010010 692 | 001000001011 693 | 111001000010 694 | 100100100100 695 | 110010101001 696 | 111101101010 697 | 111111100101 698 | 100010010001 699 | 001010010110 700 | 111101011000 701 | 001010111100 702 | 001001111110 703 | 100010100110 704 | 100001110100 705 | 001111001101 706 | 101100100111 707 | 101101100101 708 | 100101110111 709 | 000111110111 710 | 000111001000 711 | 010101000010 712 | 011000111100 713 | 001001001110 714 | 111101010001 715 | 001011010101 716 | 100011000111 717 | 100000001001 718 | 011100011110 719 | 010111011011 720 | 011000010011 721 | 101101011110 722 | 000000100011 723 | 111110010010 724 | 111010011101 725 | 001000100100 726 | 110101100001 727 | 100101101000 728 | 001110111111 729 | 010001000101 730 | 111110000101 731 | 101000001101 732 | 110101010000 733 | 111110101110 734 | 011111011000 735 | 001001001111 736 | 000101010110 737 | 001100110000 738 | 001111101000 739 | 101000100101 740 | 010000000010 741 | 110011000010 742 | 000000001100 743 | 010000101011 744 | 010101011011 745 | 101011010100 746 | 010001011011 747 | 111100011001 748 | 100000111110 749 | 110001101010 750 | 100111101001 751 | 100110001110 752 | 110001010101 753 | 101100001000 754 | 100001000010 755 | 000110100001 756 | 001010000000 757 | 011111100000 758 | 111110101111 759 | 000001101001 760 | 000000111110 761 | 101111101001 762 | 001010000010 763 | 011110010010 764 | 101111000111 765 | 111110101010 766 | 000100001000 767 | 000111000000 768 | 110010010110 769 | 000001111110 770 | 010110101010 771 | 001010100011 772 | 001111011001 773 | 111001001111 774 | 100100010111 775 | 101100001011 776 | 100111000110 777 | 111010111101 778 | 010001011110 779 | 101110000011 780 | 010111000010 781 | 110110001011 782 | 111010100011 783 | 111100011101 784 | 101101101001 785 | 110100001000 786 | 110001011001 787 | 110010100001 788 | 111110010110 789 | 010100100011 790 | 001000011101 791 | 001011001010 792 | 011100111011 793 | 001111100110 794 | 001101100110 795 | 001011000001 796 | 010100100110 797 | 100100100111 798 | 010100011011 799 | 000101110001 800 | 010110011111 801 | 000001011101 802 | 110101011001 803 | 001101101010 804 | 011111111010 805 | 111001100011 806 | 100001000111 807 | 110110011111 808 | 100101010001 809 | 011100100010 810 | 100100011000 811 | 101111001011 812 | 111001011000 813 | 110000101110 814 | 010100100101 815 | 110011101000 816 | 001101000011 817 | 111101100101 818 | 011010011011 819 | 100110001101 820 | 111001111100 821 | 001000100010 822 | 000101111101 823 | 101110011000 824 | 001011111010 825 | 111100101001 826 | 011000101001 827 | 001111010111 828 | 001100110010 829 | 011000011011 830 | 110111011000 831 | 100100000110 832 | 011010110000 833 | 110111101111 834 | 111000111101 835 | 111111100110 836 | 000101010010 837 | 010101001010 838 | 110100110101 839 | 011011100101 840 | 110110111011 841 | 100010111110 842 | 100110111010 843 | 100011001010 844 | 100100100000 845 | 101000110110 846 | 001010101010 847 | 011001101111 848 | 001110110000 849 | 010001100100 850 | 011000100100 851 | 001011001011 852 | 110111100110 853 | 010110010111 854 | 001011011010 855 | 111100001010 856 | 000010001100 857 | 011010001111 858 | 100100001101 859 | 100010011100 860 | 000010001000 861 | 101001010000 862 | 110101001101 863 | 010110111100 864 | 101001100100 865 | 100000111010 866 | 010000010001 867 | 011101011101 868 | 100011110010 869 | 100100011111 870 | 100011100101 871 | 001010010010 872 | 000110011111 873 | 010000000111 874 | 111001101101 875 | 010011000010 876 | 000001111010 877 | 010010001111 878 | 101011100001 879 | 101100111100 880 | 100001000000 881 | 110111110010 882 | 100110000111 883 | 100000111011 884 | 111010011110 885 | 011011011011 886 | 101011000110 887 | 011100011001 888 | 000101011100 889 | 010000101111 890 | 100010100001 891 | 111000100101 892 | 011010010001 893 | 110110100011 894 | 100000011100 895 | 101110101101 896 | 000010110100 897 | 101011111110 898 | 001000100111 899 | 101001001010 900 | 001111110101 901 | 001001000010 902 | 001100101110 903 | 111000001000 904 | 000000100000 905 | 000100111110 906 | 111111110100 907 | 110101001100 908 | 001100000010 909 | 100011011001 910 | 000110000010 911 | 100010101101 912 | 111110101011 913 | 110100000000 914 | 000100111001 915 | 001111001011 916 | 110111011011 917 | 001111100010 918 | 101111011010 919 | 111010011011 920 | 100111101010 921 | 011011011001 922 | 010100000011 923 | 001111010001 924 | 101010101101 925 | 110000011111 926 | 001111111111 927 | 000110000100 928 | 101111101010 929 | 101011011101 930 | 010001011010 931 | 001001011011 932 | 101011010010 933 | 111010000010 934 | 011100101000 935 | 101001011010 936 | 000111110101 937 | 110011011101 938 | 101010010011 939 | 101100001111 940 | 111001010001 941 | 100100010110 942 | 010100100001 943 | 011110110101 944 | 110100000111 945 | 110101001000 946 | 101000010000 947 | 110000000011 948 | 011111110110 949 | 100001010100 950 | 011111000101 951 | 010010101001 952 | 000111100100 953 | 001010000110 954 | 100100110110 955 | 110010101101 956 | 010001111101 957 | 101100000000 958 | 001100000000 959 | 011111111110 960 | 110001100101 961 | 000111001100 962 | 011101111110 963 | 000100110000 964 | 111111111000 965 | 101110010001 966 | 100111000010 967 | 100111011110 968 | 000100111010 969 | 110101011011 970 | 001000111110 971 | 101101110110 972 | 110110010011 973 | 011010100101 974 | 001010101111 975 | 100110111001 976 | 010001111100 977 | 010110101000 978 | 011000000000 979 | 010001011111 980 | 010101101111 981 | 111001010110 982 | 100001001011 983 | 110000100111 984 | 011100000001 985 | 110101100000 986 | 110010110010 987 | 111010111001 988 | 011010111000 989 | 101100000110 990 | 010100011111 991 | 001010111000 992 | 101100101101 993 | 011000111010 994 | 000001001100 995 | 001111010010 996 | 011010100000 997 | 110100110111 998 | 101101000100 999 | 001110001101 1000 | 111001101111 1001 | -------------------------------------------------------------------------------- /day-3-2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | if err := run(); err != nil { 12 | fmt.Fprintln(os.Stderr, err) 13 | os.Exit(1) 14 | } 15 | } 16 | 17 | func run() error { 18 | input, err := ioutil.ReadAll(os.Stdin) 19 | if err != nil { 20 | return err 21 | } 22 | answer, err := Answer(strings.TrimSpace(string(input)) + "\n") 23 | fmt.Printf("answer: %v\n", answer) 24 | return err 25 | } 26 | 27 | // See v*.go files for Answer() implementations. 28 | -------------------------------------------------------------------------------- /day-3-2/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/matryer/is" 9 | ) 10 | 11 | var exampleInput = strings.TrimSpace(` 12 | 00100s 13 | 11110 14 | 10110 15 | 10111 16 | 10101 17 | 01111 18 | 00111 19 | 11100 20 | 10000 21 | 11001 22 | 00010 23 | 01010 24 | `) + "\n" 25 | 26 | var puzzleInput = (func() string { 27 | data, err := ioutil.ReadFile("./input.txt") 28 | if err != nil { 29 | panic(err) 30 | } 31 | return strings.TrimSpace(string(data)) + "\n" 32 | })() 33 | 34 | func TestAnswer(t *testing.T) { 35 | t.Run("example", func(t *testing.T) { 36 | is := is.New(t) 37 | answer, err := Answer(exampleInput) 38 | is.NoErr(err) 39 | is.Equal(answer, 230) 40 | }) 41 | 42 | t.Run("puzzle", func(t *testing.T) { 43 | is := is.New(t) 44 | answer, err := Answer(puzzleInput) 45 | is.NoErr(err) 46 | is.Equal(answer, 2784375) 47 | }) 48 | } 49 | 50 | func BenchmarkAnswer(b *testing.B) { 51 | for i := 0; i < b.N; i++ { 52 | Answer(exampleInput) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /day-3-2/v1.go: -------------------------------------------------------------------------------- 1 | //go:build v1 2 | 3 | package main 4 | 5 | func Answer(input string) (int, error) { 6 | var numbers []string 7 | var number string 8 | for len(input) > 0 { 9 | if input[0] == '\n' { 10 | numbers = append(numbers, number) 11 | number = "" 12 | } else { 13 | number += string(input[0]) 14 | } 15 | input = input[1:] 16 | } 17 | 18 | oxygen := find(numbers, mostCommon) 19 | co2 := find(numbers, leastCommon) 20 | 21 | return oxygen * co2, nil 22 | } 23 | 24 | func find(numbers []string, filter func([]string, int) byte) int { 25 | for pos := 0; len(numbers) > 1; pos++ { 26 | needle := filter(numbers, pos) 27 | var remaining []string 28 | for _, v := range numbers { 29 | if v[pos] == needle { 30 | remaining = append(remaining, v) 31 | } 32 | } 33 | numbers = remaining 34 | } 35 | number := numbers[0] 36 | decimal := 0 37 | for i := 0; i < len(number); i++ { 38 | if number[i] == '1' { 39 | decimal |= 1 << (len(number) - i - 1) 40 | } 41 | } 42 | 43 | return decimal 44 | } 45 | 46 | func mostCommon(numbers []string, pos int) byte { 47 | oneCount := countOnes(numbers, pos) 48 | zeroCount := len(numbers) - oneCount 49 | if oneCount >= zeroCount { 50 | return '1' 51 | } 52 | return '0' 53 | } 54 | 55 | func leastCommon(numbers []string, pos int) byte { 56 | oneCount := countOnes(numbers, pos) 57 | zeroCount := len(numbers) - oneCount 58 | if oneCount < zeroCount { 59 | return '1' 60 | } 61 | return '0' 62 | } 63 | 64 | func countOnes(numbers []string, pos int) int { 65 | var oneCount int 66 | for _, v := range numbers { 67 | if v[pos] == '1' { 68 | oneCount++ 69 | } 70 | } 71 | return oneCount 72 | } 73 | -------------------------------------------------------------------------------- /day-4-1/day-4-1.test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-4-1/day-4-1.test -------------------------------------------------------------------------------- /day-4-1/input.txt: -------------------------------------------------------------------------------- 1 | 90,4,2,96,46,1,62,97,3,52,7,35,50,28,31,37,74,26,59,53,82,47,83,80,19,40,68,95,34,55,54,73,12,78,30,63,57,93,72,77,56,91,23,67,64,79,85,84,76,10,58,0,29,13,94,20,32,25,11,38,89,21,98,92,42,27,14,99,24,75,86,51,22,48,9,33,49,18,70,8,87,61,39,16,66,71,5,69,15,43,88,45,6,81,60,36,44,17,41,65 2 | 3 | 76 82 2 92 53 4 | 74 33 8 89 3 5 | 80 27 72 26 91 6 | 30 83 7 16 4 7 | 20 56 48 5 13 8 | 9 | 67 7 75 66 4 10 | 35 97 21 29 95 11 | 58 98 56 71 65 12 | 55 61 19 64 9 13 | 38 34 42 30 2 14 | 15 | 79 97 63 98 75 16 | 1 13 0 76 46 17 | 56 59 58 55 86 18 | 43 27 73 67 31 19 | 33 81 26 19 3 20 | 21 | 3 37 33 8 19 22 | 34 69 82 9 51 23 | 56 45 15 85 79 24 | 32 55 81 22 12 25 | 42 20 48 7 75 26 | 27 | 16 68 45 31 54 28 | 57 40 77 5 76 29 | 67 24 84 14 41 30 | 21 23 27 36 7 31 | 56 8 86 50 22 32 | 33 | 28 53 81 26 40 34 | 59 29 49 89 48 35 | 10 44 3 42 7 36 | 79 87 32 31 54 37 | 15 23 65 69 56 38 | 39 | 86 20 47 1 94 40 | 3 91 77 14 83 41 | 79 93 4 92 65 42 | 0 67 30 36 7 43 | 6 48 59 35 73 44 | 45 | 75 87 7 28 25 46 | 31 71 35 52 32 47 | 47 99 0 80 33 48 | 41 59 24 50 17 49 | 93 58 26 81 53 50 | 51 | 41 77 15 55 86 52 | 20 5 54 79 93 53 | 3 61 57 47 7 54 | 85 98 91 39 13 55 | 4 81 63 72 24 56 | 57 | 27 37 57 38 72 58 | 86 99 14 2 15 59 | 94 25 73 13 54 60 | 19 26 56 3 7 61 | 1 49 33 24 21 62 | 63 | 11 79 12 89 1 64 | 23 98 49 66 48 65 | 15 30 90 57 31 66 | 55 47 61 9 74 67 | 76 93 81 63 95 68 | 69 | 51 92 84 77 26 70 | 85 42 80 89 25 71 | 82 41 73 58 49 72 | 6 36 75 4 40 73 | 62 11 56 24 69 74 | 75 | 19 79 35 75 18 76 | 7 4 12 78 70 77 | 44 52 26 94 60 78 | 71 65 61 89 87 79 | 83 95 73 93 13 80 | 81 | 36 79 62 91 58 82 | 12 46 9 55 93 83 | 98 32 68 87 69 84 | 27 90 51 45 2 85 | 15 43 29 26 40 86 | 87 | 29 47 78 54 31 88 | 98 65 71 8 72 89 | 75 51 13 80 2 90 | 93 69 20 52 96 91 | 33 91 3 37 62 92 | 93 | 94 74 2 23 71 94 | 16 95 52 31 80 95 | 3 4 28 9 50 96 | 6 40 47 62 48 97 | 97 43 85 11 99 98 | 99 | 20 64 23 36 39 100 | 22 31 75 45 24 101 | 53 19 17 58 51 102 | 66 4 81 72 37 103 | 34 82 42 91 48 104 | 105 | 22 15 43 97 13 106 | 73 71 88 1 48 107 | 84 4 29 87 95 108 | 90 40 11 67 6 109 | 23 10 12 64 99 110 | 111 | 29 61 2 34 89 112 | 93 87 10 42 65 113 | 13 45 88 30 69 114 | 71 78 1 20 19 115 | 44 75 9 84 37 116 | 117 | 48 89 80 68 45 118 | 81 12 1 64 77 119 | 79 87 21 26 40 120 | 44 82 46 78 54 121 | 33 63 8 0 98 122 | 123 | 0 62 13 43 93 124 | 11 66 99 86 55 125 | 27 89 51 98 46 126 | 39 76 73 24 37 127 | 23 68 72 80 64 128 | 129 | 37 89 58 78 76 130 | 41 9 22 97 82 131 | 40 39 73 96 8 132 | 91 4 84 35 34 133 | 70 12 79 75 7 134 | 135 | 26 18 12 88 97 136 | 10 51 62 53 79 137 | 24 47 31 89 21 138 | 57 96 1 17 80 139 | 58 92 7 14 60 140 | 141 | 12 23 6 71 64 142 | 82 40 15 18 29 143 | 53 21 76 52 84 144 | 32 86 89 22 91 145 | 74 58 80 2 63 146 | 147 | 71 96 10 39 87 148 | 45 68 94 76 33 149 | 59 60 11 62 88 150 | 13 37 63 47 7 151 | 44 79 24 21 16 152 | 153 | 80 71 39 36 1 154 | 9 23 55 58 91 155 | 65 60 19 25 22 156 | 0 88 98 83 93 157 | 82 69 43 78 8 158 | 159 | 67 80 42 49 97 160 | 7 18 92 98 89 161 | 21 95 61 8 64 162 | 76 63 52 68 87 163 | 47 34 84 45 96 164 | 165 | 40 0 45 33 79 166 | 18 56 83 6 58 167 | 66 7 4 25 61 168 | 91 46 60 22 99 169 | 62 65 64 84 17 170 | 171 | 68 18 96 88 61 172 | 89 55 81 20 70 173 | 60 76 17 69 40 174 | 37 63 41 54 11 175 | 43 94 58 47 31 176 | 177 | 60 63 64 26 21 178 | 87 99 49 11 16 179 | 70 41 50 1 38 180 | 45 98 94 67 62 181 | 13 34 61 92 40 182 | 183 | 56 64 37 26 34 184 | 69 16 72 75 77 185 | 19 8 50 38 98 186 | 0 2 99 48 20 187 | 68 35 88 57 90 188 | 189 | 17 41 40 48 54 190 | 67 52 63 25 78 191 | 95 26 12 85 37 192 | 69 93 58 62 11 193 | 47 33 14 35 81 194 | 195 | 26 51 80 31 64 196 | 2 7 59 37 57 197 | 70 78 52 91 50 198 | 86 0 15 20 25 199 | 85 79 41 98 83 200 | 201 | 91 86 31 63 4 202 | 81 37 77 94 74 203 | 45 95 88 23 40 204 | 29 46 79 18 70 205 | 75 14 20 51 68 206 | 207 | 30 59 37 56 99 208 | 74 14 4 21 53 209 | 61 49 84 40 33 210 | 20 51 79 66 27 211 | 58 23 88 17 75 212 | 213 | 46 64 31 6 61 214 | 38 14 77 83 59 215 | 13 81 91 17 24 216 | 11 96 90 10 49 217 | 73 82 1 69 45 218 | 219 | 21 57 79 10 41 220 | 67 74 96 20 94 221 | 29 40 78 9 85 222 | 23 25 49 0 39 223 | 59 88 58 86 92 224 | 225 | 1 22 49 43 32 226 | 47 56 18 16 25 227 | 42 57 48 53 46 228 | 78 20 89 36 96 229 | 24 28 76 39 29 230 | 231 | 53 66 38 11 94 232 | 49 27 25 1 82 233 | 12 72 50 61 51 234 | 97 92 96 4 89 235 | 47 44 21 24 81 236 | 237 | 16 70 78 12 63 238 | 87 32 95 99 64 239 | 68 54 85 53 94 240 | 88 22 52 3 23 241 | 48 27 1 58 31 242 | 243 | 71 62 41 44 49 244 | 67 98 61 48 46 245 | 47 9 24 30 51 246 | 29 76 57 53 34 247 | 23 96 42 5 73 248 | 249 | 50 72 56 97 2 250 | 20 5 3 55 93 251 | 24 7 22 9 96 252 | 58 60 38 17 36 253 | 11 54 79 28 53 254 | 255 | 13 21 35 79 91 256 | 8 28 68 54 6 257 | 0 25 82 78 1 258 | 29 99 41 46 95 259 | 66 72 17 55 76 260 | 261 | 43 42 7 85 90 262 | 91 80 79 72 8 263 | 34 77 44 30 92 264 | 48 49 40 70 86 265 | 28 69 27 84 73 266 | 267 | 17 94 67 26 63 268 | 68 77 71 23 13 269 | 6 96 11 21 73 270 | 53 33 80 62 99 271 | 60 36 38 32 75 272 | 273 | 75 83 50 32 29 274 | 61 94 4 35 51 275 | 52 77 54 69 5 276 | 36 89 76 26 71 277 | 74 19 13 33 18 278 | 279 | 29 24 28 5 54 280 | 56 86 37 45 83 281 | 34 77 42 58 76 282 | 82 1 4 39 64 283 | 61 26 99 72 89 284 | 285 | 25 80 23 88 2 286 | 76 93 90 86 52 287 | 17 62 55 83 7 288 | 57 81 24 0 99 289 | 67 44 27 4 94 290 | 291 | 71 26 62 63 31 292 | 4 15 38 0 89 293 | 41 77 34 42 19 294 | 39 90 45 30 73 295 | 3 33 8 50 55 296 | 297 | 65 26 20 8 70 298 | 96 24 88 29 46 299 | 22 6 21 4 72 300 | 59 32 18 49 61 301 | 28 58 66 67 92 302 | 303 | 68 45 62 77 40 304 | 53 1 21 11 83 305 | 44 88 81 56 89 306 | 29 32 47 0 50 307 | 26 74 78 59 6 308 | 309 | 52 56 23 84 74 310 | 64 21 45 35 75 311 | 82 86 60 97 83 312 | 69 78 15 20 37 313 | 68 36 17 43 28 314 | 315 | 92 33 36 48 34 316 | 75 77 79 39 88 317 | 61 28 21 2 94 318 | 84 89 17 22 67 319 | 38 41 7 80 12 320 | 321 | 27 34 91 21 87 322 | 5 65 7 70 36 323 | 31 3 38 49 61 324 | 96 62 50 97 20 325 | 47 37 16 59 76 326 | 327 | 39 50 3 25 31 328 | 37 36 88 40 14 329 | 26 70 75 30 9 330 | 97 42 86 90 20 331 | 38 66 22 4 69 332 | 333 | 62 64 72 11 79 334 | 50 0 89 30 70 335 | 83 53 93 39 22 336 | 90 20 80 55 32 337 | 6 12 19 27 2 338 | 339 | 17 85 24 50 13 340 | 12 41 75 74 35 341 | 3 88 69 73 1 342 | 77 34 71 32 44 343 | 96 26 37 46 9 344 | 345 | 84 20 33 4 21 346 | 5 22 19 91 51 347 | 23 56 44 43 68 348 | 6 50 70 47 46 349 | 75 81 34 32 13 350 | 351 | 6 36 27 32 59 352 | 4 75 63 86 48 353 | 81 49 44 7 25 354 | 0 69 11 43 91 355 | 87 39 23 47 98 356 | 357 | 53 16 97 94 69 358 | 4 43 9 67 33 359 | 21 83 32 87 35 360 | 55 78 68 28 75 361 | 51 19 82 54 24 362 | 363 | 50 84 63 21 92 364 | 51 52 97 66 1 365 | 22 44 31 64 49 366 | 83 24 2 35 45 367 | 15 16 71 60 58 368 | 369 | 54 83 48 63 2 370 | 43 82 65 20 42 371 | 52 86 58 27 75 372 | 7 76 64 18 11 373 | 77 93 67 0 25 374 | 375 | 12 60 93 99 37 376 | 29 44 47 4 89 377 | 30 63 52 66 91 378 | 2 38 72 84 6 379 | 1 96 5 18 33 380 | 381 | 76 61 58 41 43 382 | 21 69 55 18 79 383 | 40 59 9 7 36 384 | 77 82 47 84 89 385 | 92 13 49 6 62 386 | 387 | 33 68 74 92 24 388 | 28 3 15 77 37 389 | 83 72 21 71 29 390 | 88 64 47 35 44 391 | 51 18 31 95 99 392 | 393 | 71 50 97 18 77 394 | 29 30 0 88 49 395 | 98 99 95 11 1 396 | 46 83 64 55 56 397 | 9 6 59 87 19 398 | 399 | 71 41 13 33 4 400 | 23 22 26 28 82 401 | 95 62 7 34 64 402 | 10 68 14 21 37 403 | 73 53 88 81 1 404 | 405 | 16 87 61 58 95 406 | 90 27 3 65 38 407 | 35 17 85 6 47 408 | 69 22 54 83 82 409 | 28 67 96 48 88 410 | 411 | 17 47 81 13 77 412 | 64 86 82 62 24 413 | 40 41 52 50 15 414 | 4 71 2 90 22 415 | 61 38 20 78 34 416 | 417 | 65 51 54 10 16 418 | 52 28 68 75 8 419 | 26 97 96 49 73 420 | 95 17 64 80 34 421 | 5 76 25 66 77 422 | 423 | 30 10 42 72 75 424 | 67 85 36 64 25 425 | 61 48 59 96 98 426 | 81 89 3 4 46 427 | 33 84 32 78 80 428 | 429 | 93 24 5 21 95 430 | 18 1 66 57 31 431 | 2 17 62 8 28 432 | 73 10 38 25 63 433 | 91 71 48 44 4 434 | 435 | 92 54 34 5 74 436 | 8 31 94 24 44 437 | 43 2 64 49 21 438 | 73 19 99 60 78 439 | 0 23 16 86 85 440 | 441 | 25 34 6 67 71 442 | 79 76 39 81 32 443 | 23 36 82 92 50 444 | 10 51 55 40 80 445 | 20 44 30 24 28 446 | 447 | 74 22 58 26 10 448 | 36 43 76 93 15 449 | 87 55 6 91 37 450 | 81 86 8 99 30 451 | 78 62 50 44 54 452 | 453 | 16 14 79 80 42 454 | 27 83 26 82 29 455 | 43 76 9 66 5 456 | 75 77 99 45 10 457 | 2 61 32 73 91 458 | 459 | 16 60 83 81 47 460 | 23 27 59 85 24 461 | 75 33 36 86 15 462 | 70 91 55 93 63 463 | 25 32 53 14 82 464 | 465 | 98 87 40 52 0 466 | 86 58 74 2 84 467 | 24 99 61 41 92 468 | 77 17 1 43 57 469 | 62 70 94 89 19 470 | 471 | 7 18 19 85 98 472 | 40 0 99 45 63 473 | 59 49 37 42 5 474 | 58 82 25 53 4 475 | 2 1 62 68 33 476 | 477 | 21 87 18 29 34 478 | 53 24 26 67 25 479 | 49 77 4 64 59 480 | 52 12 97 2 36 481 | 66 76 9 74 95 482 | 483 | 92 44 14 18 48 484 | 31 74 79 86 58 485 | 68 12 33 55 56 486 | 97 94 25 41 65 487 | 29 36 53 60 62 488 | 489 | 23 26 85 88 7 490 | 96 1 75 76 9 491 | 49 44 18 78 59 492 | 64 83 19 30 74 493 | 52 95 66 62 22 494 | 495 | 43 99 38 73 33 496 | 36 46 24 32 91 497 | 47 68 15 5 81 498 | 37 20 0 97 50 499 | 12 30 53 4 55 500 | 501 | 26 33 49 91 30 502 | 61 22 7 12 82 503 | 4 36 1 6 11 504 | 96 14 35 90 50 505 | 97 25 28 32 58 506 | 507 | 92 36 56 10 62 508 | 73 35 60 25 34 509 | 96 24 16 53 84 510 | 37 51 30 58 1 511 | 20 80 43 63 45 512 | 513 | 39 68 53 30 91 514 | 11 97 10 12 55 515 | 6 76 57 77 48 516 | 56 51 98 71 82 517 | 46 27 54 33 5 518 | 519 | 19 38 63 64 61 520 | 48 28 29 60 72 521 | 99 94 55 25 76 522 | 98 37 7 3 80 523 | 10 2 16 35 50 524 | 525 | 16 68 75 19 58 526 | 28 21 56 11 46 527 | 60 25 32 88 30 528 | 53 62 69 7 91 529 | 73 94 24 6 38 530 | 531 | 69 4 37 70 54 532 | 67 17 2 57 16 533 | 72 30 43 58 1 534 | 6 56 28 86 18 535 | 7 94 55 35 77 536 | 537 | 73 32 57 79 1 538 | 89 17 26 44 29 539 | 11 86 94 38 74 540 | 49 98 54 76 6 541 | 67 45 87 21 51 542 | 543 | 14 73 22 48 69 544 | 78 89 4 32 18 545 | 96 59 26 43 92 546 | 68 33 97 53 35 547 | 61 52 87 57 31 548 | 549 | 86 1 22 31 20 550 | 14 84 23 38 18 551 | 57 67 5 90 6 552 | 91 21 52 65 36 553 | 61 56 3 51 25 554 | 555 | 60 5 98 31 76 556 | 3 44 24 16 63 557 | 0 96 56 25 84 558 | 88 18 71 93 19 559 | 26 77 86 23 65 560 | 561 | 62 58 11 34 26 562 | 35 56 97 67 90 563 | 20 65 27 73 77 564 | 4 84 19 82 45 565 | 43 92 18 68 55 566 | 567 | 33 46 21 41 75 568 | 98 73 67 80 81 569 | 84 16 44 93 94 570 | 1 9 26 97 52 571 | 88 74 12 95 99 572 | 573 | 46 83 30 22 79 574 | 72 26 42 74 33 575 | 54 41 94 86 82 576 | 27 81 31 34 12 577 | 77 6 38 56 71 578 | 579 | 22 80 82 60 24 580 | 20 49 51 58 59 581 | 47 35 67 92 78 582 | 15 8 71 97 63 583 | 37 27 98 16 38 584 | 585 | 71 94 59 27 83 586 | 81 68 58 61 43 587 | 12 75 93 70 56 588 | 19 28 99 39 20 589 | 18 22 34 78 13 590 | 591 | 43 70 54 13 60 592 | 17 24 31 47 84 593 | 88 15 40 45 76 594 | 7 78 63 75 56 595 | 23 66 96 26 46 596 | 597 | 2 16 13 57 32 598 | 26 70 37 50 68 599 | 58 17 3 96 67 600 | 33 95 72 59 42 601 | 94 43 51 20 60 602 | -------------------------------------------------------------------------------- /day-4-1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | if err := run(); err != nil { 12 | fmt.Fprintln(os.Stderr, err) 13 | os.Exit(1) 14 | } 15 | } 16 | 17 | func run() error { 18 | input, err := ioutil.ReadAll(os.Stdin) 19 | if err != nil { 20 | return err 21 | } 22 | answer, err := Answer(strings.TrimSpace(string(input)) + "\n") 23 | fmt.Printf("answer: %v\n", answer) 24 | return err 25 | } 26 | 27 | // See v*.go files for Answer() implementations. 28 | -------------------------------------------------------------------------------- /day-4-1/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/matryer/is" 9 | ) 10 | 11 | var exampleInput = strings.TrimSpace(` 12 | 7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1 13 | 14 | 22 13 17 11 0 15 | 8 2 23 4 24 16 | 21 9 14 16 7 17 | 6 10 3 18 5 18 | 1 12 20 15 19 19 | 20 | 3 15 0 2 22 21 | 9 18 13 17 5 22 | 19 8 7 25 23 23 | 20 11 10 24 4 24 | 14 21 16 12 6 25 | 26 | 14 21 17 24 4 27 | 10 16 15 9 19 28 | 18 8 23 26 20 29 | 22 11 13 6 5 30 | 2 0 12 3 7 31 | `) + "\n" 32 | 33 | var puzzleInput = (func() string { 34 | data, err := ioutil.ReadFile("./input.txt") 35 | if err != nil { 36 | panic(err) 37 | } 38 | return strings.TrimSpace(string(data)) + "\n" 39 | })() 40 | 41 | func TestGame(t *testing.T) { 42 | t.Run("parse", func(t *testing.T) { 43 | is := is.New(t) 44 | var g Game 45 | is.NoErr(g.Parse(exampleInput)) 46 | 47 | is.Equal(len(g.numbers), 27) 48 | is.Equal(g.numbers[0], 7) 49 | is.Equal(g.numbers[len(g.numbers)-1], 1) 50 | 51 | is.Equal(len(g.boards), 3) 52 | for _, b := range g.boards { 53 | is.Equal(len(b.numbers), 25) 54 | } 55 | is.Equal(g.boards[0].numbers[0], 22) 56 | is.Equal(g.boards[0].numbers[len(g.boards[0].numbers)-1], 19) 57 | is.Equal(g.boards[1].numbers[0], 3) 58 | is.Equal(g.boards[1].numbers[len(g.boards[0].numbers)-1], 6) 59 | is.Equal(g.boards[2].numbers[0], 14) 60 | is.Equal(g.boards[2].numbers[len(g.boards[0].numbers)-1], 7) 61 | }) 62 | } 63 | 64 | func TestAnswer(t *testing.T) { 65 | t.Run("example", func(t *testing.T) { 66 | is := is.New(t) 67 | answer, err := Answer(exampleInput) 68 | is.NoErr(err) 69 | is.Equal(answer, 4512) 70 | }) 71 | 72 | t.Run("puzzle", func(t *testing.T) { 73 | is := is.New(t) 74 | answer, err := Answer(puzzleInput) 75 | is.NoErr(err) 76 | is.Equal(answer, 8136) 77 | }) 78 | } 79 | 80 | func BenchmarkAnswer(b *testing.B) { 81 | b.ReportAllocs() 82 | for i := 0; i < b.N; i++ { 83 | Answer(puzzleInput) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /day-4-1/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-4-1/v1.cpu.pprof -------------------------------------------------------------------------------- /day-4-1/v1.go: -------------------------------------------------------------------------------- 1 | //go:build v1 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "io" 8 | ) 9 | 10 | func Answer(input string) (int, error) { 11 | var g Game 12 | if err := g.Parse(input); err != nil { 13 | return 0, err 14 | } 15 | return g.Play() 16 | } 17 | 18 | type Game struct { 19 | numbers []int 20 | boards []Board 21 | } 22 | 23 | func (g *Game) Parse(input string) error { 24 | const ( 25 | inputDigit = 1 26 | inputNl = 2 27 | boardDigit = 3 28 | boardSpace = 4 29 | boardNl = 5 30 | ) 31 | 32 | var ( 33 | state = inputDigit 34 | number = 0 35 | board = NewBoard() 36 | ) 37 | 38 | for i := 0; i < len(input); i++ { 39 | c := input[i] 40 | switch state { 41 | case inputDigit: 42 | if c == ',' || c == '\n' { 43 | g.numbers = append(g.numbers, number) 44 | number = 0 45 | if c == '\n' { 46 | state = inputNl 47 | } 48 | } else if c >= '0' && c <= '9' { 49 | number = number*10 + int(c) - '0' 50 | } else { 51 | return fmt.Errorf("bad inputDigit: %q", string(c)) 52 | } 53 | case inputNl: 54 | if c == '\n' { 55 | state = boardSpace 56 | } else { 57 | return fmt.Errorf("bad inputNl: %q", string(c)) 58 | } 59 | case boardDigit: 60 | if c == ' ' { 61 | board.Add(number) 62 | number = 0 63 | state = boardSpace 64 | } else if c == '\n' { 65 | board.Add(number) 66 | number = 0 67 | state = boardNl 68 | } else if c >= '0' && c <= '9' { 69 | number = number*10 + int(c) - '0' 70 | state = boardDigit 71 | } else { 72 | return fmt.Errorf("bad boardDigit: %q", string(c)) 73 | } 74 | case boardSpace: 75 | if c == ' ' { 76 | // do nothing 77 | } else if c >= '0' && c <= '9' { 78 | number = number*10 + int(c) - '0' 79 | state = boardDigit 80 | } else { 81 | return fmt.Errorf("bad boardNl: %q", string(c)) 82 | } 83 | case boardNl: 84 | if c == ' ' { 85 | state = boardSpace 86 | } else if c == '\n' { 87 | g.boards = append(g.boards, board) 88 | board = NewBoard() 89 | state = boardSpace 90 | } else if c >= '0' && c <= '9' { 91 | number = number*10 + int(c) - '0' 92 | state = boardDigit 93 | } else { 94 | return fmt.Errorf("bad boardNl: %q", string(c)) 95 | } 96 | } 97 | } 98 | g.boards = append(g.boards, board) 99 | return nil 100 | } 101 | 102 | func (g *Game) Play() (int, error) { 103 | for _, number := range g.numbers { 104 | for i := range g.boards { 105 | if result := g.boards[i].Mark(number); result != -1 { 106 | return result, nil 107 | } 108 | } 109 | } 110 | return 0, io.EOF 111 | } 112 | 113 | const boardSize = 5 114 | 115 | func NewBoard() Board { 116 | return Board{ 117 | numbers: make([]int, 0, boardSize*boardSize), 118 | marked: make([]bool, boardSize*boardSize), 119 | } 120 | } 121 | 122 | type Board struct { 123 | numbers []int 124 | marked []bool 125 | } 126 | 127 | func (b *Board) Add(number int) { 128 | b.numbers = append(b.numbers, number) 129 | } 130 | 131 | func (b *Board) Mark(number int) int { 132 | for i, boardNumber := range b.numbers { 133 | if boardNumber == number { 134 | b.marked[i] = true 135 | if b.won(i) { 136 | return number * b.sumUnmarked() 137 | } 138 | } 139 | } 140 | return -1 141 | } 142 | 143 | func (b *Board) won(i int) bool { 144 | row, col := b.rowCol(i) 145 | var cols int 146 | for checkCol := 0; checkCol < boardSize; checkCol++ { 147 | if b.marked[b.offset(row, checkCol)] { 148 | cols++ 149 | } 150 | } 151 | if cols == boardSize { 152 | return true 153 | } 154 | var rows int 155 | for checkRow := 0; checkRow < boardSize; checkRow++ { 156 | if b.marked[b.offset(checkRow, col)] { 157 | rows++ 158 | } 159 | } 160 | return rows == boardSize 161 | } 162 | 163 | func (b *Board) sumUnmarked() (sum int) { 164 | for i, number := range b.numbers { 165 | if !b.marked[i] { 166 | sum += number 167 | } 168 | } 169 | return 170 | } 171 | 172 | func (b *Board) rowCol(offset int) (int, int) { 173 | row := offset / boardSize 174 | col := offset - row*boardSize 175 | return row, col 176 | } 177 | 178 | func (b *Board) offset(row, col int) int { 179 | return row*boardSize + col 180 | } 181 | -------------------------------------------------------------------------------- /day-4-1/v1.mem.prof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-4-1/v1.mem.prof -------------------------------------------------------------------------------- /day-4-1/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-4-1 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 10000 107638 ns/op 38282 B/op 216 allocs/op 6 | BenchmarkAnswer-6 10000 103393 ns/op 38280 B/op 216 allocs/op 7 | BenchmarkAnswer-6 10000 103772 ns/op 38280 B/op 216 allocs/op 8 | BenchmarkAnswer-6 10000 103235 ns/op 38281 B/op 216 allocs/op 9 | BenchmarkAnswer-6 10000 103107 ns/op 38280 B/op 216 allocs/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-4-1 5.436s 12 | -------------------------------------------------------------------------------- /day-4-2/day-4-2.test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-4-2/day-4-2.test -------------------------------------------------------------------------------- /day-4-2/input.txt: -------------------------------------------------------------------------------- 1 | 90,4,2,96,46,1,62,97,3,52,7,35,50,28,31,37,74,26,59,53,82,47,83,80,19,40,68,95,34,55,54,73,12,78,30,63,57,93,72,77,56,91,23,67,64,79,85,84,76,10,58,0,29,13,94,20,32,25,11,38,89,21,98,92,42,27,14,99,24,75,86,51,22,48,9,33,49,18,70,8,87,61,39,16,66,71,5,69,15,43,88,45,6,81,60,36,44,17,41,65 2 | 3 | 76 82 2 92 53 4 | 74 33 8 89 3 5 | 80 27 72 26 91 6 | 30 83 7 16 4 7 | 20 56 48 5 13 8 | 9 | 67 7 75 66 4 10 | 35 97 21 29 95 11 | 58 98 56 71 65 12 | 55 61 19 64 9 13 | 38 34 42 30 2 14 | 15 | 79 97 63 98 75 16 | 1 13 0 76 46 17 | 56 59 58 55 86 18 | 43 27 73 67 31 19 | 33 81 26 19 3 20 | 21 | 3 37 33 8 19 22 | 34 69 82 9 51 23 | 56 45 15 85 79 24 | 32 55 81 22 12 25 | 42 20 48 7 75 26 | 27 | 16 68 45 31 54 28 | 57 40 77 5 76 29 | 67 24 84 14 41 30 | 21 23 27 36 7 31 | 56 8 86 50 22 32 | 33 | 28 53 81 26 40 34 | 59 29 49 89 48 35 | 10 44 3 42 7 36 | 79 87 32 31 54 37 | 15 23 65 69 56 38 | 39 | 86 20 47 1 94 40 | 3 91 77 14 83 41 | 79 93 4 92 65 42 | 0 67 30 36 7 43 | 6 48 59 35 73 44 | 45 | 75 87 7 28 25 46 | 31 71 35 52 32 47 | 47 99 0 80 33 48 | 41 59 24 50 17 49 | 93 58 26 81 53 50 | 51 | 41 77 15 55 86 52 | 20 5 54 79 93 53 | 3 61 57 47 7 54 | 85 98 91 39 13 55 | 4 81 63 72 24 56 | 57 | 27 37 57 38 72 58 | 86 99 14 2 15 59 | 94 25 73 13 54 60 | 19 26 56 3 7 61 | 1 49 33 24 21 62 | 63 | 11 79 12 89 1 64 | 23 98 49 66 48 65 | 15 30 90 57 31 66 | 55 47 61 9 74 67 | 76 93 81 63 95 68 | 69 | 51 92 84 77 26 70 | 85 42 80 89 25 71 | 82 41 73 58 49 72 | 6 36 75 4 40 73 | 62 11 56 24 69 74 | 75 | 19 79 35 75 18 76 | 7 4 12 78 70 77 | 44 52 26 94 60 78 | 71 65 61 89 87 79 | 83 95 73 93 13 80 | 81 | 36 79 62 91 58 82 | 12 46 9 55 93 83 | 98 32 68 87 69 84 | 27 90 51 45 2 85 | 15 43 29 26 40 86 | 87 | 29 47 78 54 31 88 | 98 65 71 8 72 89 | 75 51 13 80 2 90 | 93 69 20 52 96 91 | 33 91 3 37 62 92 | 93 | 94 74 2 23 71 94 | 16 95 52 31 80 95 | 3 4 28 9 50 96 | 6 40 47 62 48 97 | 97 43 85 11 99 98 | 99 | 20 64 23 36 39 100 | 22 31 75 45 24 101 | 53 19 17 58 51 102 | 66 4 81 72 37 103 | 34 82 42 91 48 104 | 105 | 22 15 43 97 13 106 | 73 71 88 1 48 107 | 84 4 29 87 95 108 | 90 40 11 67 6 109 | 23 10 12 64 99 110 | 111 | 29 61 2 34 89 112 | 93 87 10 42 65 113 | 13 45 88 30 69 114 | 71 78 1 20 19 115 | 44 75 9 84 37 116 | 117 | 48 89 80 68 45 118 | 81 12 1 64 77 119 | 79 87 21 26 40 120 | 44 82 46 78 54 121 | 33 63 8 0 98 122 | 123 | 0 62 13 43 93 124 | 11 66 99 86 55 125 | 27 89 51 98 46 126 | 39 76 73 24 37 127 | 23 68 72 80 64 128 | 129 | 37 89 58 78 76 130 | 41 9 22 97 82 131 | 40 39 73 96 8 132 | 91 4 84 35 34 133 | 70 12 79 75 7 134 | 135 | 26 18 12 88 97 136 | 10 51 62 53 79 137 | 24 47 31 89 21 138 | 57 96 1 17 80 139 | 58 92 7 14 60 140 | 141 | 12 23 6 71 64 142 | 82 40 15 18 29 143 | 53 21 76 52 84 144 | 32 86 89 22 91 145 | 74 58 80 2 63 146 | 147 | 71 96 10 39 87 148 | 45 68 94 76 33 149 | 59 60 11 62 88 150 | 13 37 63 47 7 151 | 44 79 24 21 16 152 | 153 | 80 71 39 36 1 154 | 9 23 55 58 91 155 | 65 60 19 25 22 156 | 0 88 98 83 93 157 | 82 69 43 78 8 158 | 159 | 67 80 42 49 97 160 | 7 18 92 98 89 161 | 21 95 61 8 64 162 | 76 63 52 68 87 163 | 47 34 84 45 96 164 | 165 | 40 0 45 33 79 166 | 18 56 83 6 58 167 | 66 7 4 25 61 168 | 91 46 60 22 99 169 | 62 65 64 84 17 170 | 171 | 68 18 96 88 61 172 | 89 55 81 20 70 173 | 60 76 17 69 40 174 | 37 63 41 54 11 175 | 43 94 58 47 31 176 | 177 | 60 63 64 26 21 178 | 87 99 49 11 16 179 | 70 41 50 1 38 180 | 45 98 94 67 62 181 | 13 34 61 92 40 182 | 183 | 56 64 37 26 34 184 | 69 16 72 75 77 185 | 19 8 50 38 98 186 | 0 2 99 48 20 187 | 68 35 88 57 90 188 | 189 | 17 41 40 48 54 190 | 67 52 63 25 78 191 | 95 26 12 85 37 192 | 69 93 58 62 11 193 | 47 33 14 35 81 194 | 195 | 26 51 80 31 64 196 | 2 7 59 37 57 197 | 70 78 52 91 50 198 | 86 0 15 20 25 199 | 85 79 41 98 83 200 | 201 | 91 86 31 63 4 202 | 81 37 77 94 74 203 | 45 95 88 23 40 204 | 29 46 79 18 70 205 | 75 14 20 51 68 206 | 207 | 30 59 37 56 99 208 | 74 14 4 21 53 209 | 61 49 84 40 33 210 | 20 51 79 66 27 211 | 58 23 88 17 75 212 | 213 | 46 64 31 6 61 214 | 38 14 77 83 59 215 | 13 81 91 17 24 216 | 11 96 90 10 49 217 | 73 82 1 69 45 218 | 219 | 21 57 79 10 41 220 | 67 74 96 20 94 221 | 29 40 78 9 85 222 | 23 25 49 0 39 223 | 59 88 58 86 92 224 | 225 | 1 22 49 43 32 226 | 47 56 18 16 25 227 | 42 57 48 53 46 228 | 78 20 89 36 96 229 | 24 28 76 39 29 230 | 231 | 53 66 38 11 94 232 | 49 27 25 1 82 233 | 12 72 50 61 51 234 | 97 92 96 4 89 235 | 47 44 21 24 81 236 | 237 | 16 70 78 12 63 238 | 87 32 95 99 64 239 | 68 54 85 53 94 240 | 88 22 52 3 23 241 | 48 27 1 58 31 242 | 243 | 71 62 41 44 49 244 | 67 98 61 48 46 245 | 47 9 24 30 51 246 | 29 76 57 53 34 247 | 23 96 42 5 73 248 | 249 | 50 72 56 97 2 250 | 20 5 3 55 93 251 | 24 7 22 9 96 252 | 58 60 38 17 36 253 | 11 54 79 28 53 254 | 255 | 13 21 35 79 91 256 | 8 28 68 54 6 257 | 0 25 82 78 1 258 | 29 99 41 46 95 259 | 66 72 17 55 76 260 | 261 | 43 42 7 85 90 262 | 91 80 79 72 8 263 | 34 77 44 30 92 264 | 48 49 40 70 86 265 | 28 69 27 84 73 266 | 267 | 17 94 67 26 63 268 | 68 77 71 23 13 269 | 6 96 11 21 73 270 | 53 33 80 62 99 271 | 60 36 38 32 75 272 | 273 | 75 83 50 32 29 274 | 61 94 4 35 51 275 | 52 77 54 69 5 276 | 36 89 76 26 71 277 | 74 19 13 33 18 278 | 279 | 29 24 28 5 54 280 | 56 86 37 45 83 281 | 34 77 42 58 76 282 | 82 1 4 39 64 283 | 61 26 99 72 89 284 | 285 | 25 80 23 88 2 286 | 76 93 90 86 52 287 | 17 62 55 83 7 288 | 57 81 24 0 99 289 | 67 44 27 4 94 290 | 291 | 71 26 62 63 31 292 | 4 15 38 0 89 293 | 41 77 34 42 19 294 | 39 90 45 30 73 295 | 3 33 8 50 55 296 | 297 | 65 26 20 8 70 298 | 96 24 88 29 46 299 | 22 6 21 4 72 300 | 59 32 18 49 61 301 | 28 58 66 67 92 302 | 303 | 68 45 62 77 40 304 | 53 1 21 11 83 305 | 44 88 81 56 89 306 | 29 32 47 0 50 307 | 26 74 78 59 6 308 | 309 | 52 56 23 84 74 310 | 64 21 45 35 75 311 | 82 86 60 97 83 312 | 69 78 15 20 37 313 | 68 36 17 43 28 314 | 315 | 92 33 36 48 34 316 | 75 77 79 39 88 317 | 61 28 21 2 94 318 | 84 89 17 22 67 319 | 38 41 7 80 12 320 | 321 | 27 34 91 21 87 322 | 5 65 7 70 36 323 | 31 3 38 49 61 324 | 96 62 50 97 20 325 | 47 37 16 59 76 326 | 327 | 39 50 3 25 31 328 | 37 36 88 40 14 329 | 26 70 75 30 9 330 | 97 42 86 90 20 331 | 38 66 22 4 69 332 | 333 | 62 64 72 11 79 334 | 50 0 89 30 70 335 | 83 53 93 39 22 336 | 90 20 80 55 32 337 | 6 12 19 27 2 338 | 339 | 17 85 24 50 13 340 | 12 41 75 74 35 341 | 3 88 69 73 1 342 | 77 34 71 32 44 343 | 96 26 37 46 9 344 | 345 | 84 20 33 4 21 346 | 5 22 19 91 51 347 | 23 56 44 43 68 348 | 6 50 70 47 46 349 | 75 81 34 32 13 350 | 351 | 6 36 27 32 59 352 | 4 75 63 86 48 353 | 81 49 44 7 25 354 | 0 69 11 43 91 355 | 87 39 23 47 98 356 | 357 | 53 16 97 94 69 358 | 4 43 9 67 33 359 | 21 83 32 87 35 360 | 55 78 68 28 75 361 | 51 19 82 54 24 362 | 363 | 50 84 63 21 92 364 | 51 52 97 66 1 365 | 22 44 31 64 49 366 | 83 24 2 35 45 367 | 15 16 71 60 58 368 | 369 | 54 83 48 63 2 370 | 43 82 65 20 42 371 | 52 86 58 27 75 372 | 7 76 64 18 11 373 | 77 93 67 0 25 374 | 375 | 12 60 93 99 37 376 | 29 44 47 4 89 377 | 30 63 52 66 91 378 | 2 38 72 84 6 379 | 1 96 5 18 33 380 | 381 | 76 61 58 41 43 382 | 21 69 55 18 79 383 | 40 59 9 7 36 384 | 77 82 47 84 89 385 | 92 13 49 6 62 386 | 387 | 33 68 74 92 24 388 | 28 3 15 77 37 389 | 83 72 21 71 29 390 | 88 64 47 35 44 391 | 51 18 31 95 99 392 | 393 | 71 50 97 18 77 394 | 29 30 0 88 49 395 | 98 99 95 11 1 396 | 46 83 64 55 56 397 | 9 6 59 87 19 398 | 399 | 71 41 13 33 4 400 | 23 22 26 28 82 401 | 95 62 7 34 64 402 | 10 68 14 21 37 403 | 73 53 88 81 1 404 | 405 | 16 87 61 58 95 406 | 90 27 3 65 38 407 | 35 17 85 6 47 408 | 69 22 54 83 82 409 | 28 67 96 48 88 410 | 411 | 17 47 81 13 77 412 | 64 86 82 62 24 413 | 40 41 52 50 15 414 | 4 71 2 90 22 415 | 61 38 20 78 34 416 | 417 | 65 51 54 10 16 418 | 52 28 68 75 8 419 | 26 97 96 49 73 420 | 95 17 64 80 34 421 | 5 76 25 66 77 422 | 423 | 30 10 42 72 75 424 | 67 85 36 64 25 425 | 61 48 59 96 98 426 | 81 89 3 4 46 427 | 33 84 32 78 80 428 | 429 | 93 24 5 21 95 430 | 18 1 66 57 31 431 | 2 17 62 8 28 432 | 73 10 38 25 63 433 | 91 71 48 44 4 434 | 435 | 92 54 34 5 74 436 | 8 31 94 24 44 437 | 43 2 64 49 21 438 | 73 19 99 60 78 439 | 0 23 16 86 85 440 | 441 | 25 34 6 67 71 442 | 79 76 39 81 32 443 | 23 36 82 92 50 444 | 10 51 55 40 80 445 | 20 44 30 24 28 446 | 447 | 74 22 58 26 10 448 | 36 43 76 93 15 449 | 87 55 6 91 37 450 | 81 86 8 99 30 451 | 78 62 50 44 54 452 | 453 | 16 14 79 80 42 454 | 27 83 26 82 29 455 | 43 76 9 66 5 456 | 75 77 99 45 10 457 | 2 61 32 73 91 458 | 459 | 16 60 83 81 47 460 | 23 27 59 85 24 461 | 75 33 36 86 15 462 | 70 91 55 93 63 463 | 25 32 53 14 82 464 | 465 | 98 87 40 52 0 466 | 86 58 74 2 84 467 | 24 99 61 41 92 468 | 77 17 1 43 57 469 | 62 70 94 89 19 470 | 471 | 7 18 19 85 98 472 | 40 0 99 45 63 473 | 59 49 37 42 5 474 | 58 82 25 53 4 475 | 2 1 62 68 33 476 | 477 | 21 87 18 29 34 478 | 53 24 26 67 25 479 | 49 77 4 64 59 480 | 52 12 97 2 36 481 | 66 76 9 74 95 482 | 483 | 92 44 14 18 48 484 | 31 74 79 86 58 485 | 68 12 33 55 56 486 | 97 94 25 41 65 487 | 29 36 53 60 62 488 | 489 | 23 26 85 88 7 490 | 96 1 75 76 9 491 | 49 44 18 78 59 492 | 64 83 19 30 74 493 | 52 95 66 62 22 494 | 495 | 43 99 38 73 33 496 | 36 46 24 32 91 497 | 47 68 15 5 81 498 | 37 20 0 97 50 499 | 12 30 53 4 55 500 | 501 | 26 33 49 91 30 502 | 61 22 7 12 82 503 | 4 36 1 6 11 504 | 96 14 35 90 50 505 | 97 25 28 32 58 506 | 507 | 92 36 56 10 62 508 | 73 35 60 25 34 509 | 96 24 16 53 84 510 | 37 51 30 58 1 511 | 20 80 43 63 45 512 | 513 | 39 68 53 30 91 514 | 11 97 10 12 55 515 | 6 76 57 77 48 516 | 56 51 98 71 82 517 | 46 27 54 33 5 518 | 519 | 19 38 63 64 61 520 | 48 28 29 60 72 521 | 99 94 55 25 76 522 | 98 37 7 3 80 523 | 10 2 16 35 50 524 | 525 | 16 68 75 19 58 526 | 28 21 56 11 46 527 | 60 25 32 88 30 528 | 53 62 69 7 91 529 | 73 94 24 6 38 530 | 531 | 69 4 37 70 54 532 | 67 17 2 57 16 533 | 72 30 43 58 1 534 | 6 56 28 86 18 535 | 7 94 55 35 77 536 | 537 | 73 32 57 79 1 538 | 89 17 26 44 29 539 | 11 86 94 38 74 540 | 49 98 54 76 6 541 | 67 45 87 21 51 542 | 543 | 14 73 22 48 69 544 | 78 89 4 32 18 545 | 96 59 26 43 92 546 | 68 33 97 53 35 547 | 61 52 87 57 31 548 | 549 | 86 1 22 31 20 550 | 14 84 23 38 18 551 | 57 67 5 90 6 552 | 91 21 52 65 36 553 | 61 56 3 51 25 554 | 555 | 60 5 98 31 76 556 | 3 44 24 16 63 557 | 0 96 56 25 84 558 | 88 18 71 93 19 559 | 26 77 86 23 65 560 | 561 | 62 58 11 34 26 562 | 35 56 97 67 90 563 | 20 65 27 73 77 564 | 4 84 19 82 45 565 | 43 92 18 68 55 566 | 567 | 33 46 21 41 75 568 | 98 73 67 80 81 569 | 84 16 44 93 94 570 | 1 9 26 97 52 571 | 88 74 12 95 99 572 | 573 | 46 83 30 22 79 574 | 72 26 42 74 33 575 | 54 41 94 86 82 576 | 27 81 31 34 12 577 | 77 6 38 56 71 578 | 579 | 22 80 82 60 24 580 | 20 49 51 58 59 581 | 47 35 67 92 78 582 | 15 8 71 97 63 583 | 37 27 98 16 38 584 | 585 | 71 94 59 27 83 586 | 81 68 58 61 43 587 | 12 75 93 70 56 588 | 19 28 99 39 20 589 | 18 22 34 78 13 590 | 591 | 43 70 54 13 60 592 | 17 24 31 47 84 593 | 88 15 40 45 76 594 | 7 78 63 75 56 595 | 23 66 96 26 46 596 | 597 | 2 16 13 57 32 598 | 26 70 37 50 68 599 | 58 17 3 96 67 600 | 33 95 72 59 42 601 | 94 43 51 20 60 602 | -------------------------------------------------------------------------------- /day-4-2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | if err := run(); err != nil { 12 | fmt.Fprintln(os.Stderr, err) 13 | os.Exit(1) 14 | } 15 | } 16 | 17 | func run() error { 18 | input, err := ioutil.ReadAll(os.Stdin) 19 | if err != nil { 20 | return err 21 | } 22 | answer, err := Answer(strings.TrimSpace(string(input)) + "\n") 23 | fmt.Printf("answer: %v\n", answer) 24 | return err 25 | } 26 | 27 | // See v*.go files for Answer() implementations. 28 | -------------------------------------------------------------------------------- /day-4-2/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/matryer/is" 9 | ) 10 | 11 | var exampleInput = strings.TrimSpace(` 12 | 7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1 13 | 14 | 22 13 17 11 0 15 | 8 2 23 4 24 16 | 21 9 14 16 7 17 | 6 10 3 18 5 18 | 1 12 20 15 19 19 | 20 | 3 15 0 2 22 21 | 9 18 13 17 5 22 | 19 8 7 25 23 23 | 20 11 10 24 4 24 | 14 21 16 12 6 25 | 26 | 14 21 17 24 4 27 | 10 16 15 9 19 28 | 18 8 23 26 20 29 | 22 11 13 6 5 30 | 2 0 12 3 7 31 | `) + "\n" 32 | 33 | var puzzleInput = (func() string { 34 | data, err := ioutil.ReadFile("./input.txt") 35 | if err != nil { 36 | panic(err) 37 | } 38 | return strings.TrimSpace(string(data)) + "\n" 39 | })() 40 | 41 | func TestGame(t *testing.T) { 42 | t.Run("parse", func(t *testing.T) { 43 | is := is.New(t) 44 | var g Game 45 | is.NoErr(g.Parse(exampleInput)) 46 | 47 | is.Equal(len(g.numbers), 27) 48 | is.Equal(g.numbers[0], 7) 49 | is.Equal(g.numbers[len(g.numbers)-1], 1) 50 | 51 | is.Equal(len(g.boards), 3) 52 | for _, b := range g.boards { 53 | is.Equal(len(b.numbers), 25) 54 | } 55 | is.Equal(g.boards[0].numbers[0], 22) 56 | is.Equal(g.boards[0].numbers[len(g.boards[0].numbers)-1], 19) 57 | is.Equal(g.boards[1].numbers[0], 3) 58 | is.Equal(g.boards[1].numbers[len(g.boards[0].numbers)-1], 6) 59 | is.Equal(g.boards[2].numbers[0], 14) 60 | is.Equal(g.boards[2].numbers[len(g.boards[0].numbers)-1], 7) 61 | }) 62 | } 63 | 64 | func TestAnswer(t *testing.T) { 65 | t.Run("example", func(t *testing.T) { 66 | is := is.New(t) 67 | answer, err := Answer(exampleInput) 68 | is.NoErr(err) 69 | is.Equal(answer, 1924) 70 | }) 71 | 72 | t.Run("puzzle", func(t *testing.T) { 73 | is := is.New(t) 74 | answer, err := Answer(puzzleInput) 75 | is.NoErr(err) 76 | is.Equal(answer, 12738) 77 | }) 78 | } 79 | 80 | func BenchmarkAnswer(b *testing.B) { 81 | b.ReportAllocs() 82 | for i := 0; i < b.N; i++ { 83 | Answer(puzzleInput) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /day-4-2/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-4-2/v1.cpu.pprof -------------------------------------------------------------------------------- /day-4-2/v1.go: -------------------------------------------------------------------------------- 1 | //go:build v1 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "io" 8 | ) 9 | 10 | func Answer(input string) (int, error) { 11 | var g Game 12 | if err := g.Parse(input); err != nil { 13 | return 0, err 14 | } 15 | return g.Play() 16 | } 17 | 18 | type Game struct { 19 | numbers []int 20 | boards []Board 21 | } 22 | 23 | func (g *Game) Parse(input string) error { 24 | const ( 25 | inputDigit = 1 26 | inputNl = 2 27 | boardDigit = 3 28 | boardSpace = 4 29 | boardNl = 5 30 | ) 31 | 32 | var ( 33 | state = inputDigit 34 | number = 0 35 | board = NewBoard() 36 | ) 37 | 38 | for i := 0; i < len(input); i++ { 39 | c := input[i] 40 | switch state { 41 | case inputDigit: 42 | if c == ',' || c == '\n' { 43 | g.numbers = append(g.numbers, number) 44 | number = 0 45 | if c == '\n' { 46 | state = inputNl 47 | } 48 | } else if c >= '0' && c <= '9' { 49 | number = number*10 + int(c) - '0' 50 | } else { 51 | return fmt.Errorf("bad inputDigit: %q", string(c)) 52 | } 53 | case inputNl: 54 | if c == '\n' { 55 | state = boardSpace 56 | } else { 57 | return fmt.Errorf("bad inputNl: %q", string(c)) 58 | } 59 | case boardDigit: 60 | if c == ' ' { 61 | board.Add(number) 62 | number = 0 63 | state = boardSpace 64 | } else if c == '\n' { 65 | board.Add(number) 66 | number = 0 67 | state = boardNl 68 | } else if c >= '0' && c <= '9' { 69 | number = number*10 + int(c) - '0' 70 | state = boardDigit 71 | } else { 72 | return fmt.Errorf("bad boardDigit: %q", string(c)) 73 | } 74 | case boardSpace: 75 | if c == ' ' { 76 | // do nothing 77 | } else if c >= '0' && c <= '9' { 78 | number = number*10 + int(c) - '0' 79 | state = boardDigit 80 | } else { 81 | return fmt.Errorf("bad boardNl: %q", string(c)) 82 | } 83 | case boardNl: 84 | if c == ' ' { 85 | state = boardSpace 86 | } else if c == '\n' { 87 | g.boards = append(g.boards, board) 88 | board = NewBoard() 89 | state = boardSpace 90 | } else if c >= '0' && c <= '9' { 91 | number = number*10 + int(c) - '0' 92 | state = boardDigit 93 | } else { 94 | return fmt.Errorf("bad boardNl: %q", string(c)) 95 | } 96 | } 97 | } 98 | g.boards = append(g.boards, board) 99 | return nil 100 | } 101 | 102 | func (g *Game) Play() (int, error) { 103 | for _, number := range g.numbers { 104 | var remainingBoards []Board 105 | for i := range g.boards { 106 | if result := g.boards[i].Mark(number); result != -1 { 107 | if len(remainingBoards) == 0 && i == len(g.boards)-1 { 108 | return result, nil 109 | } 110 | } else { 111 | remainingBoards = append(remainingBoards, g.boards[i]) 112 | } 113 | } 114 | g.boards = remainingBoards 115 | } 116 | return 0, io.EOF 117 | } 118 | 119 | const boardSize = 5 120 | 121 | func NewBoard() Board { 122 | return Board{ 123 | numbers: make([]int, 0, boardSize*boardSize), 124 | marked: make([]bool, boardSize*boardSize), 125 | } 126 | } 127 | 128 | type Board struct { 129 | numbers []int 130 | marked []bool 131 | } 132 | 133 | func (b *Board) Add(number int) { 134 | b.numbers = append(b.numbers, number) 135 | } 136 | 137 | func (b *Board) Mark(number int) int { 138 | for i, boardNumber := range b.numbers { 139 | if boardNumber == number { 140 | b.marked[i] = true 141 | if b.won(i) { 142 | return number * b.sumUnmarked() 143 | } 144 | } 145 | } 146 | return -1 147 | } 148 | 149 | func (b *Board) won(i int) bool { 150 | row, col := b.rowCol(i) 151 | var cols int 152 | for checkCol := 0; checkCol < boardSize; checkCol++ { 153 | if b.marked[b.offset(row, checkCol)] { 154 | cols++ 155 | } 156 | } 157 | if cols == boardSize { 158 | return true 159 | } 160 | var rows int 161 | for checkRow := 0; checkRow < boardSize; checkRow++ { 162 | if b.marked[b.offset(checkRow, col)] { 163 | rows++ 164 | } 165 | } 166 | return rows == boardSize 167 | } 168 | 169 | func (b *Board) sumUnmarked() (sum int) { 170 | for i, number := range b.numbers { 171 | if !b.marked[i] { 172 | sum += number 173 | } 174 | } 175 | return 176 | } 177 | 178 | func (b *Board) rowCol(offset int) (int, int) { 179 | row := offset / boardSize 180 | col := offset - row*boardSize 181 | return row, col 182 | } 183 | 184 | func (b *Board) offset(row, col int) int { 185 | return row*boardSize + col 186 | } 187 | -------------------------------------------------------------------------------- /day-4-2/v1.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-4-2/v1.mem.pprof -------------------------------------------------------------------------------- /day-4-2/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-4-2 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 2814 380946 ns/op 780280 B/op 802 allocs/op 6 | BenchmarkAnswer-6 2947 374243 ns/op 780278 B/op 802 allocs/op 7 | BenchmarkAnswer-6 2924 380128 ns/op 780281 B/op 802 allocs/op 8 | BenchmarkAnswer-6 2943 373536 ns/op 780275 B/op 802 allocs/op 9 | BenchmarkAnswer-6 2955 377812 ns/op 780274 B/op 802 allocs/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-4-2 5.830s 12 | -------------------------------------------------------------------------------- /day-5-1/cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-1/cpu.pprof -------------------------------------------------------------------------------- /day-5-1/day-5-1.test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-1/day-5-1.test -------------------------------------------------------------------------------- /day-5-1/input.txt: -------------------------------------------------------------------------------- 1 | 957,596 -> 957,182 2 | 763,144 -> 69,144 3 | 761,794 -> 911,944 4 | 510,440 -> 147,440 5 | 859,33 -> 859,409 6 | 602,518 -> 748,518 7 | 980,545 -> 676,241 8 | 60,528 -> 616,528 9 | 37,242 -> 37,892 10 | 216,966 -> 216,120 11 | 372,910 -> 372,307 12 | 688,864 -> 94,864 13 | 691,17 -> 167,17 14 | 989,928 -> 989,816 15 | 207,84 -> 982,84 16 | 890,714 -> 502,326 17 | 286,329 -> 686,329 18 | 959,62 -> 460,62 19 | 840,82 -> 780,82 20 | 960,12 -> 14,958 21 | 418,45 -> 983,610 22 | 318,264 -> 988,934 23 | 458,11 -> 861,11 24 | 805,197 -> 380,622 25 | 261,907 -> 261,734 26 | 409,617 -> 826,617 27 | 285,457 -> 759,931 28 | 104,241 -> 913,241 29 | 781,141 -> 781,671 30 | 48,956 -> 348,956 31 | 921,517 -> 974,517 32 | 565,621 -> 724,621 33 | 381,276 -> 381,59 34 | 82,25 -> 946,25 35 | 978,16 -> 17,977 36 | 850,438 -> 125,438 37 | 313,850 -> 313,195 38 | 789,963 -> 789,29 39 | 110,156 -> 241,156 40 | 925,974 -> 458,974 41 | 93,153 -> 696,756 42 | 748,312 -> 120,312 43 | 566,367 -> 360,367 44 | 687,295 -> 687,284 45 | 219,925 -> 180,925 46 | 59,952 -> 59,140 47 | 641,333 -> 361,53 48 | 158,587 -> 158,96 49 | 857,278 -> 857,195 50 | 653,45 -> 34,664 51 | 639,384 -> 814,384 52 | 67,24 -> 902,859 53 | 850,278 -> 850,448 54 | 342,505 -> 342,287 55 | 504,924 -> 536,956 56 | 408,666 -> 408,310 57 | 747,347 -> 747,176 58 | 766,468 -> 54,468 59 | 283,905 -> 283,421 60 | 476,334 -> 476,59 61 | 490,935 -> 753,672 62 | 385,772 -> 940,772 63 | 907,316 -> 853,370 64 | 144,717 -> 746,115 65 | 741,819 -> 230,819 66 | 524,397 -> 524,237 67 | 411,824 -> 288,824 68 | 160,719 -> 744,135 69 | 252,550 -> 440,738 70 | 902,64 -> 902,422 71 | 392,194 -> 955,757 72 | 937,735 -> 937,446 73 | 292,49 -> 985,49 74 | 899,464 -> 481,46 75 | 304,369 -> 648,369 76 | 247,723 -> 247,697 77 | 665,941 -> 185,461 78 | 548,25 -> 446,127 79 | 663,558 -> 154,558 80 | 52,47 -> 872,867 81 | 983,68 -> 983,795 82 | 492,705 -> 654,867 83 | 82,888 -> 33,888 84 | 550,443 -> 229,764 85 | 868,508 -> 375,15 86 | 120,829 -> 652,829 87 | 787,296 -> 814,296 88 | 705,643 -> 351,643 89 | 52,23 -> 558,23 90 | 390,92 -> 390,393 91 | 713,520 -> 897,520 92 | 280,481 -> 827,481 93 | 599,181 -> 599,235 94 | 483,140 -> 773,140 95 | 571,227 -> 571,779 96 | 830,45 -> 830,745 97 | 617,745 -> 449,745 98 | 89,176 -> 841,928 99 | 358,868 -> 906,320 100 | 897,669 -> 654,669 101 | 717,729 -> 123,135 102 | 305,330 -> 305,598 103 | 220,964 -> 600,964 104 | 607,715 -> 492,715 105 | 837,561 -> 820,561 106 | 542,38 -> 542,118 107 | 390,970 -> 915,445 108 | 343,160 -> 475,160 109 | 163,60 -> 972,869 110 | 786,500 -> 946,500 111 | 401,393 -> 401,910 112 | 336,962 -> 528,962 113 | 520,489 -> 520,525 114 | 558,584 -> 363,584 115 | 786,880 -> 584,678 116 | 704,435 -> 153,986 117 | 356,522 -> 235,643 118 | 225,67 -> 229,71 119 | 389,381 -> 55,47 120 | 918,229 -> 332,229 121 | 558,989 -> 558,370 122 | 307,821 -> 307,447 123 | 13,232 -> 742,961 124 | 659,809 -> 467,809 125 | 905,942 -> 456,942 126 | 234,810 -> 234,497 127 | 421,287 -> 643,65 128 | 183,164 -> 312,164 129 | 652,955 -> 977,630 130 | 157,820 -> 853,124 131 | 278,480 -> 278,384 132 | 504,399 -> 298,605 133 | 955,76 -> 798,76 134 | 565,352 -> 109,352 135 | 912,16 -> 66,862 136 | 972,786 -> 235,49 137 | 146,15 -> 146,186 138 | 944,149 -> 497,596 139 | 485,84 -> 762,84 140 | 975,983 -> 16,24 141 | 11,896 -> 887,20 142 | 826,924 -> 126,224 143 | 246,648 -> 158,736 144 | 773,377 -> 582,377 145 | 296,947 -> 378,865 146 | 592,291 -> 592,861 147 | 331,470 -> 16,470 148 | 239,85 -> 705,85 149 | 409,842 -> 409,966 150 | 145,438 -> 145,340 151 | 239,859 -> 239,409 152 | 651,508 -> 314,845 153 | 720,39 -> 176,583 154 | 762,444 -> 762,29 155 | 983,962 -> 60,39 156 | 745,248 -> 91,902 157 | 990,18 -> 990,503 158 | 441,472 -> 441,211 159 | 524,837 -> 248,561 160 | 160,215 -> 842,897 161 | 469,544 -> 989,544 162 | 311,241 -> 103,33 163 | 887,610 -> 746,610 164 | 377,942 -> 377,803 165 | 920,401 -> 823,401 166 | 10,142 -> 10,486 167 | 850,955 -> 850,578 168 | 887,728 -> 887,678 169 | 555,749 -> 84,749 170 | 839,620 -> 32,620 171 | 432,709 -> 432,183 172 | 312,164 -> 859,711 173 | 20,119 -> 739,838 174 | 930,871 -> 324,265 175 | 41,702 -> 41,520 176 | 48,210 -> 794,956 177 | 479,526 -> 479,123 178 | 364,739 -> 364,379 179 | 920,969 -> 73,122 180 | 382,314 -> 382,604 181 | 969,877 -> 129,37 182 | 274,893 -> 52,671 183 | 696,296 -> 696,221 184 | 469,735 -> 626,892 185 | 682,435 -> 682,937 186 | 626,550 -> 626,604 187 | 898,904 -> 898,755 188 | 836,849 -> 445,458 189 | 405,237 -> 405,724 190 | 253,74 -> 908,729 191 | 837,802 -> 597,802 192 | 375,450 -> 316,450 193 | 621,784 -> 314,784 194 | 856,136 -> 188,804 195 | 983,11 -> 29,965 196 | 82,134 -> 752,134 197 | 677,299 -> 573,299 198 | 43,726 -> 43,304 199 | 886,629 -> 886,603 200 | 439,471 -> 74,836 201 | 973,879 -> 122,28 202 | 550,246 -> 497,246 203 | 49,109 -> 816,876 204 | 294,493 -> 271,493 205 | 495,397 -> 495,342 206 | 846,892 -> 881,927 207 | 267,397 -> 72,592 208 | 670,168 -> 22,816 209 | 482,302 -> 482,681 210 | 309,692 -> 453,692 211 | 597,369 -> 597,589 212 | 518,475 -> 633,475 213 | 391,484 -> 493,382 214 | 177,135 -> 139,135 215 | 458,17 -> 825,17 216 | 514,292 -> 272,50 217 | 410,734 -> 142,734 218 | 465,975 -> 542,898 219 | 32,901 -> 346,587 220 | 390,478 -> 571,659 221 | 835,839 -> 189,839 222 | 769,407 -> 769,788 223 | 974,40 -> 103,911 224 | 710,709 -> 246,709 225 | 468,857 -> 343,982 226 | 777,552 -> 951,552 227 | 23,490 -> 346,490 228 | 270,384 -> 855,384 229 | 386,454 -> 166,454 230 | 166,388 -> 319,388 231 | 698,514 -> 698,180 232 | 554,162 -> 528,162 233 | 651,363 -> 879,363 234 | 327,123 -> 327,255 235 | 439,492 -> 719,212 236 | 903,438 -> 903,356 237 | 99,611 -> 99,552 238 | 512,652 -> 45,185 239 | 565,284 -> 565,180 240 | 81,710 -> 637,154 241 | 321,769 -> 164,769 242 | 32,307 -> 32,204 243 | 310,338 -> 310,914 244 | 239,691 -> 357,691 245 | 573,164 -> 559,164 246 | 887,961 -> 693,767 247 | 362,904 -> 362,944 248 | 467,294 -> 236,294 249 | 182,53 -> 182,264 250 | 19,950 -> 951,18 251 | 191,575 -> 440,824 252 | 192,168 -> 690,666 253 | 538,552 -> 891,905 254 | 243,38 -> 243,403 255 | 417,140 -> 417,818 256 | 894,45 -> 726,213 257 | 245,898 -> 245,527 258 | 567,946 -> 567,983 259 | 572,675 -> 363,675 260 | 318,618 -> 735,618 261 | 616,580 -> 981,580 262 | 37,881 -> 134,881 263 | 624,675 -> 271,322 264 | 323,686 -> 770,686 265 | 93,385 -> 626,385 266 | 715,382 -> 862,382 267 | 170,342 -> 170,84 268 | 747,221 -> 380,221 269 | 981,311 -> 981,577 270 | 372,186 -> 372,826 271 | 961,91 -> 130,922 272 | 48,603 -> 48,110 273 | 34,975 -> 935,74 274 | 707,18 -> 707,192 275 | 261,149 -> 41,369 276 | 35,589 -> 35,247 277 | 544,522 -> 437,522 278 | 797,712 -> 346,712 279 | 622,47 -> 78,591 280 | 642,390 -> 642,414 281 | 793,29 -> 69,29 282 | 978,905 -> 978,296 283 | 212,515 -> 212,920 284 | 835,166 -> 68,933 285 | 168,742 -> 168,720 286 | 390,276 -> 666,276 287 | 507,792 -> 987,792 288 | 895,242 -> 895,402 289 | 121,950 -> 943,128 290 | 303,336 -> 303,205 291 | 293,390 -> 293,736 292 | 433,963 -> 433,867 293 | 824,327 -> 620,531 294 | 553,689 -> 867,689 295 | 226,984 -> 226,284 296 | 153,308 -> 173,308 297 | 855,959 -> 345,959 298 | 830,895 -> 830,981 299 | 557,63 -> 557,205 300 | 51,857 -> 328,857 301 | 224,243 -> 224,517 302 | 830,773 -> 830,520 303 | 607,210 -> 782,385 304 | 876,330 -> 327,330 305 | 985,11 -> 18,978 306 | 352,936 -> 111,936 307 | 900,39 -> 986,39 308 | 10,626 -> 10,795 309 | 369,942 -> 11,942 310 | 136,770 -> 654,252 311 | 209,541 -> 209,557 312 | 69,671 -> 848,671 313 | 811,451 -> 194,451 314 | 149,46 -> 850,747 315 | 704,386 -> 704,953 316 | 117,346 -> 387,346 317 | 238,701 -> 688,251 318 | 789,220 -> 789,815 319 | 967,512 -> 967,213 320 | 641,652 -> 151,162 321 | 91,942 -> 312,942 322 | 42,226 -> 801,985 323 | 166,37 -> 603,37 324 | 854,976 -> 951,976 325 | 392,23 -> 772,23 326 | 299,196 -> 299,288 327 | 514,560 -> 844,890 328 | 618,699 -> 348,429 329 | 604,947 -> 604,735 330 | 189,851 -> 407,633 331 | 907,719 -> 907,449 332 | 167,421 -> 864,421 333 | 491,383 -> 538,383 334 | 939,504 -> 939,433 335 | 78,649 -> 78,975 336 | 817,246 -> 322,741 337 | 395,195 -> 205,195 338 | 872,275 -> 872,500 339 | 196,621 -> 280,621 340 | 634,619 -> 634,422 341 | 395,30 -> 395,232 342 | 895,628 -> 619,904 343 | 58,66 -> 186,194 344 | 626,477 -> 708,559 345 | 747,712 -> 747,28 346 | 935,798 -> 220,798 347 | 459,530 -> 704,530 348 | 648,679 -> 79,110 349 | 778,135 -> 778,66 350 | 657,352 -> 906,352 351 | 499,160 -> 615,160 352 | 830,226 -> 830,489 353 | 364,971 -> 826,971 354 | 879,923 -> 543,923 355 | 914,984 -> 612,984 356 | 594,810 -> 508,810 357 | 55,467 -> 269,253 358 | 360,478 -> 360,902 359 | 176,890 -> 176,431 360 | 867,121 -> 16,972 361 | 728,876 -> 65,213 362 | 606,112 -> 842,112 363 | 563,532 -> 914,532 364 | 783,139 -> 369,139 365 | 564,359 -> 846,359 366 | 79,326 -> 15,390 367 | 972,419 -> 972,35 368 | 686,839 -> 755,839 369 | 427,856 -> 77,856 370 | 102,410 -> 925,410 371 | 468,177 -> 901,610 372 | 865,249 -> 930,314 373 | 784,447 -> 863,368 374 | 684,708 -> 223,708 375 | 555,228 -> 555,900 376 | 380,600 -> 222,600 377 | 900,408 -> 188,408 378 | 773,677 -> 773,16 379 | 560,287 -> 560,790 380 | 130,851 -> 959,22 381 | 338,951 -> 626,663 382 | 678,726 -> 405,726 383 | 243,469 -> 243,276 384 | 783,486 -> 66,486 385 | 469,536 -> 469,770 386 | 689,148 -> 689,340 387 | 396,689 -> 396,673 388 | 848,759 -> 848,770 389 | 965,775 -> 965,605 390 | 889,907 -> 284,302 391 | 161,169 -> 942,950 392 | 619,267 -> 394,492 393 | 323,786 -> 18,481 394 | 953,643 -> 884,643 395 | 371,446 -> 371,252 396 | 890,915 -> 192,217 397 | 674,259 -> 674,247 398 | 877,479 -> 877,117 399 | 620,843 -> 620,734 400 | 597,722 -> 597,939 401 | 935,663 -> 935,469 402 | 108,844 -> 108,596 403 | 211,447 -> 211,482 404 | 123,657 -> 721,59 405 | 774,858 -> 774,86 406 | 978,500 -> 978,305 407 | 152,890 -> 937,105 408 | 728,356 -> 728,261 409 | 354,373 -> 433,452 410 | 586,627 -> 586,949 411 | 764,381 -> 735,410 412 | 986,899 -> 199,112 413 | 251,418 -> 251,596 414 | 897,379 -> 897,388 415 | 149,901 -> 253,901 416 | 650,229 -> 46,229 417 | 446,707 -> 446,44 418 | 953,898 -> 697,898 419 | 772,422 -> 762,432 420 | 608,756 -> 927,756 421 | 138,911 -> 716,333 422 | 414,583 -> 244,583 423 | 219,267 -> 219,751 424 | 69,746 -> 69,886 425 | 444,243 -> 493,194 426 | 604,950 -> 244,950 427 | 450,198 -> 31,617 428 | 918,852 -> 109,43 429 | 967,800 -> 267,100 430 | 388,516 -> 760,516 431 | 656,954 -> 513,954 432 | 80,680 -> 80,44 433 | 360,848 -> 360,800 434 | 10,10 -> 989,989 435 | 889,927 -> 104,142 436 | 882,187 -> 812,187 437 | 416,522 -> 356,522 438 | 797,795 -> 273,271 439 | 175,371 -> 12,371 440 | 726,595 -> 956,595 441 | 852,355 -> 852,357 442 | 959,83 -> 338,83 443 | 822,766 -> 140,84 444 | 968,129 -> 181,916 445 | 17,28 -> 975,986 446 | 15,913 -> 624,304 447 | 589,322 -> 468,443 448 | 894,21 -> 309,606 449 | 83,25 -> 963,905 450 | 143,380 -> 377,146 451 | 587,151 -> 507,151 452 | 257,967 -> 257,882 453 | 770,552 -> 770,573 454 | 128,90 -> 886,848 455 | 456,953 -> 456,669 456 | 930,434 -> 668,434 457 | 501,835 -> 796,540 458 | 36,980 -> 989,27 459 | 494,690 -> 626,690 460 | 105,945 -> 972,78 461 | 409,730 -> 409,62 462 | 901,160 -> 831,90 463 | 881,490 -> 28,490 464 | 736,244 -> 38,942 465 | 295,770 -> 199,770 466 | 866,416 -> 808,416 467 | 875,716 -> 875,189 468 | 763,393 -> 241,915 469 | 583,237 -> 704,237 470 | 29,153 -> 637,153 471 | 767,282 -> 767,107 472 | 456,242 -> 456,165 473 | 455,232 -> 749,232 474 | 54,128 -> 766,840 475 | 901,73 -> 939,73 476 | 928,118 -> 854,118 477 | 15,983 -> 975,23 478 | 600,92 -> 260,92 479 | 247,714 -> 247,490 480 | 511,332 -> 19,824 481 | 55,15 -> 968,928 482 | 246,29 -> 25,29 483 | 22,101 -> 761,840 484 | 876,177 -> 139,914 485 | 165,150 -> 822,807 486 | 258,707 -> 773,707 487 | 68,788 -> 68,875 488 | 858,142 -> 758,142 489 | 719,642 -> 810,642 490 | 928,904 -> 928,338 491 | 287,977 -> 978,286 492 | 883,13 -> 883,31 493 | 681,301 -> 681,957 494 | 762,863 -> 405,506 495 | 194,657 -> 733,118 496 | 78,41 -> 497,41 497 | 840,627 -> 840,168 498 | 335,54 -> 335,822 499 | 136,983 -> 526,593 500 | 120,156 -> 120,630 501 | -------------------------------------------------------------------------------- /day-5-1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | if err := run(); err != nil { 12 | fmt.Fprintln(os.Stderr, err) 13 | os.Exit(1) 14 | } 15 | } 16 | 17 | func run() error { 18 | input, err := ioutil.ReadAll(os.Stdin) 19 | if err != nil { 20 | return err 21 | } 22 | answer, err := Answer(strings.TrimSpace(string(input)) + "\n") 23 | fmt.Printf("answer: %v\n", answer) 24 | return err 25 | } 26 | 27 | // See v*.go files for Answer() implementations. 28 | -------------------------------------------------------------------------------- /day-5-1/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | var exampleInput = strings.TrimSpace(` 12 | 0,9 -> 5,9 13 | 8,0 -> 0,8 14 | 9,4 -> 3,4 15 | 2,2 -> 2,1 16 | 7,0 -> 7,4 17 | 6,4 -> 2,0 18 | 0,9 -> 2,9 19 | 3,4 -> 1,4 20 | 0,0 -> 8,8 21 | 5,5 -> 8,2 22 | `) + "\n" 23 | 24 | var puzzleInput = (func() string { 25 | data, err := ioutil.ReadFile("./input.txt") 26 | if err != nil { 27 | panic(err) 28 | } 29 | return strings.TrimSpace(string(data)) + "\n" 30 | })() 31 | 32 | func TestGrid(t *testing.T) { 33 | t.Run("Get", func(t *testing.T) { 34 | g := NewGrid(3, 4) 35 | require.Equal(t, 0, g.Get(0, 0)) 36 | require.Equal(t, 0, g.Get(2, 3)) 37 | require.Panics(t, func() { 38 | g.Get(2, 4) 39 | }) 40 | require.Panics(t, func() { 41 | g.Get(3, 3) 42 | }) 43 | }) 44 | 45 | t.Run("Set", func(t *testing.T) { 46 | g := NewGrid(3, 4) 47 | g.Set(0, 0, 2) 48 | g.Set(2, 3, 3) 49 | require.Equal(t, 2, g.Get(0, 0)) 50 | require.Equal(t, 3, g.Get(2, 3)) 51 | }) 52 | 53 | t.Run("String", func(t *testing.T) { 54 | g := NewGrid(2, 3) 55 | require.Equal(t, "..\n..\n..", g.String()) 56 | g.Set(0, 0, 3) 57 | g.Set(0, 1, 7) 58 | g.Set(1, 2, 5) 59 | require.Equal(t, "3.\n7.\n.5", g.String()) 60 | }) 61 | } 62 | 63 | func BenchmarkGrid(b *testing.B) { 64 | g := NewGrid(10, 15) 65 | for i := 0; i < b.N; i++ { 66 | g.Set(i%10, i%15, i) 67 | _ = g.Get(i%10, i%15) 68 | } 69 | } 70 | 71 | func TestInput(t *testing.T) { 72 | t.Run("ParseInput", func(t *testing.T) { 73 | input, err := ParseInput(exampleInput) 74 | require.NoError(t, err) 75 | 76 | require.Equal(t, 0, input.lines[0].X1) 77 | require.Equal(t, 9, input.lines[0].Y1) 78 | require.Equal(t, 5, input.lines[0].X2) 79 | require.Equal(t, 9, input.lines[0].Y2) 80 | 81 | require.Equal(t, 5, input.lines[9].X1) 82 | require.Equal(t, 5, input.lines[9].Y1) 83 | require.Equal(t, 8, input.lines[9].X2) 84 | require.Equal(t, 2, input.lines[9].Y2) 85 | 86 | input, err = ParseInput(puzzleInput) 87 | require.NoError(t, err) 88 | require.Equal(t, 957, input.lines[0].X1) 89 | require.Equal(t, 596, input.lines[0].Y1) 90 | require.Equal(t, 957, input.lines[0].X2) 91 | require.Equal(t, 182, input.lines[0].Y2) 92 | }) 93 | 94 | t.Run("Grid", func(t *testing.T) { 95 | input, err := ParseInput(exampleInput) 96 | require.NoError(t, err) 97 | grid := input.Grid() 98 | want := strings.TrimSpace(` 99 | .......1.. 100 | ..1....1.. 101 | ..1....1.. 102 | .......1.. 103 | .112111211 104 | .......... 105 | .......... 106 | .......... 107 | .......... 108 | 222111.... 109 | `) 110 | require.Equal(t, want, grid.String()) 111 | }) 112 | } 113 | 114 | func TestAnswer(t *testing.T) { 115 | t.Run("example", func(t *testing.T) { 116 | answer, err := Answer(exampleInput) 117 | require.NoError(t, err) 118 | require.Equal(t, 5, answer) 119 | }) 120 | 121 | t.Run("puzzle", func(t *testing.T) { 122 | answer, err := Answer(puzzleInput) 123 | require.NoError(t, err) 124 | require.Equal(t, answer, 6311) 125 | }) 126 | } 127 | 128 | func BenchmarkAnswer(b *testing.B) { 129 | b.ReportAllocs() 130 | for i := 0; i < b.N; i++ { 131 | Answer(puzzleInput) 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /day-5-1/mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-1/mem.pprof -------------------------------------------------------------------------------- /day-5-1/v1.go: -------------------------------------------------------------------------------- 1 | //go:build v1 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func Answer(inputText string) (int, error) { 12 | input, err := ParseInput(inputText) 13 | if err != nil { 14 | return 0, err 15 | } 16 | return input.Grid().Count(func(val int) bool { 17 | return val >= 2 18 | }), nil 19 | } 20 | 21 | func ParseInput(text string) (*Input, error) { 22 | // parser states 23 | const ( 24 | x1 = iota 25 | y1 26 | arrowSpace 27 | arrowDash 28 | arrowGt 29 | x2 30 | y2 31 | ) 32 | 33 | var ( 34 | input Input 35 | state = x1 36 | line Line 37 | ) 38 | 39 | for i := 0; i < len(text); i++ { 40 | c := text[i] 41 | switch state { 42 | case x1: 43 | if c >= '0' && c <= '9' { 44 | line.X1 = line.X1*10 + int(c) - '0' 45 | } else if c == ',' { 46 | state = y1 47 | } else { 48 | return nil, fmt.Errorf("x1: bad char: %q", string(c)) 49 | } 50 | case y1: 51 | if c >= '0' && c <= '9' { 52 | line.Y1 = line.Y1*10 + int(c) - '0' 53 | } else if c == ' ' { 54 | state = arrowSpace 55 | } else { 56 | return nil, fmt.Errorf("y1: bad char: %q", string(c)) 57 | } 58 | case arrowSpace: 59 | if c == '-' { 60 | state = arrowDash 61 | } else { 62 | return nil, fmt.Errorf("arrowSpace: bad char: %q", string(c)) 63 | } 64 | case arrowDash: 65 | if c == '>' { 66 | state = arrowGt 67 | } else { 68 | return nil, fmt.Errorf("arrowDash: bad char: %q", string(c)) 69 | } 70 | case arrowGt: 71 | if c == ' ' { 72 | state = x2 73 | } else { 74 | return nil, fmt.Errorf("arrowGt: bad char: %q", string(c)) 75 | } 76 | case x2: 77 | if c >= '0' && c <= '9' { 78 | line.X2 = line.X2*10 + int(c) - '0' 79 | } else if c == ',' { 80 | state = y2 81 | } else { 82 | return nil, fmt.Errorf("x2: bad char: %q", string(c)) 83 | } 84 | case y2: 85 | if c >= '0' && c <= '9' { 86 | line.Y2 = line.Y2*10 + int(c) - '0' 87 | } else if c == '\n' { 88 | input.lines = append(input.lines, line) 89 | line = Line{} 90 | state = x1 91 | } else { 92 | return nil, fmt.Errorf("y2: bad char: %q", string(c)) 93 | } 94 | } 95 | } 96 | return &input, nil 97 | } 98 | 99 | type Input struct { 100 | lines []Line 101 | } 102 | 103 | func (i *Input) Grid() Grid { 104 | var ( 105 | width = -1 106 | height = -1 107 | ) 108 | for _, l := range i.lines { 109 | if l.X1 > width { 110 | width = l.X1 111 | } 112 | if l.X2 > width { 113 | width = l.X2 114 | } 115 | if l.Y1 > height { 116 | height = l.Y1 117 | } 118 | if l.Y2 > height { 119 | height = l.Y2 120 | } 121 | } 122 | 123 | g := NewGrid(width+1, height+1) 124 | for _, l := range i.lines { 125 | if l.X1 == l.X2 { 126 | // vertical line 127 | yMin, yMax := sortAsc(l.Y1, l.Y2) 128 | for y := yMin; y <= yMax; y++ { 129 | g.Inc(l.X1, y) 130 | } 131 | } else if l.Y1 == l.Y2 { 132 | // horizontal line 133 | xMin, xMax := sortAsc(l.X1, l.X2) 134 | for x := xMin; x <= xMax; x++ { 135 | g.Inc(x, l.Y1) 136 | } 137 | } 138 | } 139 | 140 | return g 141 | } 142 | 143 | func sortAsc(a, b int) (int, int) { 144 | if a < b { 145 | return a, b 146 | } else { 147 | return b, a 148 | } 149 | } 150 | 151 | type Line struct { 152 | X1 int 153 | Y1 int 154 | X2 int 155 | Y2 int 156 | } 157 | 158 | func NewGrid(width, height int) Grid { 159 | return Grid{ 160 | data: make([]int, width*height), 161 | width: width, 162 | height: height, 163 | } 164 | } 165 | 166 | type Grid struct { 167 | data []int 168 | width int 169 | height int 170 | } 171 | 172 | func (g Grid) Get(x, y int) int { 173 | return g.data[g.offset(x, y)] 174 | } 175 | 176 | func (g Grid) Set(x, y, val int) { 177 | g.data[g.offset(x, y)] = val 178 | } 179 | 180 | func (g Grid) Inc(x, y int) { 181 | g.data[g.offset(x, y)]++ 182 | } 183 | 184 | func (g Grid) Count(fn func(val int) bool) (count int) { 185 | for _, v := range g.data { 186 | if fn(v) { 187 | count++ 188 | } 189 | } 190 | return 191 | } 192 | 193 | func (g Grid) offset(x, y int) int { 194 | return y*g.width + x 195 | } 196 | 197 | func (g Grid) String() string { 198 | var lines []string 199 | for y := 0; y < g.height; y++ { 200 | var line string 201 | for x := 0; x < g.width; x++ { 202 | val := g.Get(x, y) 203 | var char string 204 | if val == 0 { 205 | char = "." 206 | } else { 207 | char = strconv.Itoa(val) 208 | } 209 | line += char 210 | } 211 | lines = append(lines, line) 212 | } 213 | return strings.Join(lines, "\n") 214 | } 215 | -------------------------------------------------------------------------------- /day-5-1/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-5-1 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 332 3290024 ns/op 7888895 B/op 12 allocs/op 6 | BenchmarkAnswer-6 348 3234918 ns/op 7888897 B/op 12 allocs/op 7 | BenchmarkAnswer-6 345 3211646 ns/op 7888890 B/op 12 allocs/op 8 | BenchmarkAnswer-6 348 3202170 ns/op 7888888 B/op 12 allocs/op 9 | BenchmarkAnswer-6 350 3184486 ns/op 7888890 B/op 12 allocs/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-5-1 7.449s 12 | -------------------------------------------------------------------------------- /day-5-2/day-5-2.test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-2/day-5-2.test -------------------------------------------------------------------------------- /day-5-2/input.txt: -------------------------------------------------------------------------------- 1 | 957,596 -> 957,182 2 | 763,144 -> 69,144 3 | 761,794 -> 911,944 4 | 510,440 -> 147,440 5 | 859,33 -> 859,409 6 | 602,518 -> 748,518 7 | 980,545 -> 676,241 8 | 60,528 -> 616,528 9 | 37,242 -> 37,892 10 | 216,966 -> 216,120 11 | 372,910 -> 372,307 12 | 688,864 -> 94,864 13 | 691,17 -> 167,17 14 | 989,928 -> 989,816 15 | 207,84 -> 982,84 16 | 890,714 -> 502,326 17 | 286,329 -> 686,329 18 | 959,62 -> 460,62 19 | 840,82 -> 780,82 20 | 960,12 -> 14,958 21 | 418,45 -> 983,610 22 | 318,264 -> 988,934 23 | 458,11 -> 861,11 24 | 805,197 -> 380,622 25 | 261,907 -> 261,734 26 | 409,617 -> 826,617 27 | 285,457 -> 759,931 28 | 104,241 -> 913,241 29 | 781,141 -> 781,671 30 | 48,956 -> 348,956 31 | 921,517 -> 974,517 32 | 565,621 -> 724,621 33 | 381,276 -> 381,59 34 | 82,25 -> 946,25 35 | 978,16 -> 17,977 36 | 850,438 -> 125,438 37 | 313,850 -> 313,195 38 | 789,963 -> 789,29 39 | 110,156 -> 241,156 40 | 925,974 -> 458,974 41 | 93,153 -> 696,756 42 | 748,312 -> 120,312 43 | 566,367 -> 360,367 44 | 687,295 -> 687,284 45 | 219,925 -> 180,925 46 | 59,952 -> 59,140 47 | 641,333 -> 361,53 48 | 158,587 -> 158,96 49 | 857,278 -> 857,195 50 | 653,45 -> 34,664 51 | 639,384 -> 814,384 52 | 67,24 -> 902,859 53 | 850,278 -> 850,448 54 | 342,505 -> 342,287 55 | 504,924 -> 536,956 56 | 408,666 -> 408,310 57 | 747,347 -> 747,176 58 | 766,468 -> 54,468 59 | 283,905 -> 283,421 60 | 476,334 -> 476,59 61 | 490,935 -> 753,672 62 | 385,772 -> 940,772 63 | 907,316 -> 853,370 64 | 144,717 -> 746,115 65 | 741,819 -> 230,819 66 | 524,397 -> 524,237 67 | 411,824 -> 288,824 68 | 160,719 -> 744,135 69 | 252,550 -> 440,738 70 | 902,64 -> 902,422 71 | 392,194 -> 955,757 72 | 937,735 -> 937,446 73 | 292,49 -> 985,49 74 | 899,464 -> 481,46 75 | 304,369 -> 648,369 76 | 247,723 -> 247,697 77 | 665,941 -> 185,461 78 | 548,25 -> 446,127 79 | 663,558 -> 154,558 80 | 52,47 -> 872,867 81 | 983,68 -> 983,795 82 | 492,705 -> 654,867 83 | 82,888 -> 33,888 84 | 550,443 -> 229,764 85 | 868,508 -> 375,15 86 | 120,829 -> 652,829 87 | 787,296 -> 814,296 88 | 705,643 -> 351,643 89 | 52,23 -> 558,23 90 | 390,92 -> 390,393 91 | 713,520 -> 897,520 92 | 280,481 -> 827,481 93 | 599,181 -> 599,235 94 | 483,140 -> 773,140 95 | 571,227 -> 571,779 96 | 830,45 -> 830,745 97 | 617,745 -> 449,745 98 | 89,176 -> 841,928 99 | 358,868 -> 906,320 100 | 897,669 -> 654,669 101 | 717,729 -> 123,135 102 | 305,330 -> 305,598 103 | 220,964 -> 600,964 104 | 607,715 -> 492,715 105 | 837,561 -> 820,561 106 | 542,38 -> 542,118 107 | 390,970 -> 915,445 108 | 343,160 -> 475,160 109 | 163,60 -> 972,869 110 | 786,500 -> 946,500 111 | 401,393 -> 401,910 112 | 336,962 -> 528,962 113 | 520,489 -> 520,525 114 | 558,584 -> 363,584 115 | 786,880 -> 584,678 116 | 704,435 -> 153,986 117 | 356,522 -> 235,643 118 | 225,67 -> 229,71 119 | 389,381 -> 55,47 120 | 918,229 -> 332,229 121 | 558,989 -> 558,370 122 | 307,821 -> 307,447 123 | 13,232 -> 742,961 124 | 659,809 -> 467,809 125 | 905,942 -> 456,942 126 | 234,810 -> 234,497 127 | 421,287 -> 643,65 128 | 183,164 -> 312,164 129 | 652,955 -> 977,630 130 | 157,820 -> 853,124 131 | 278,480 -> 278,384 132 | 504,399 -> 298,605 133 | 955,76 -> 798,76 134 | 565,352 -> 109,352 135 | 912,16 -> 66,862 136 | 972,786 -> 235,49 137 | 146,15 -> 146,186 138 | 944,149 -> 497,596 139 | 485,84 -> 762,84 140 | 975,983 -> 16,24 141 | 11,896 -> 887,20 142 | 826,924 -> 126,224 143 | 246,648 -> 158,736 144 | 773,377 -> 582,377 145 | 296,947 -> 378,865 146 | 592,291 -> 592,861 147 | 331,470 -> 16,470 148 | 239,85 -> 705,85 149 | 409,842 -> 409,966 150 | 145,438 -> 145,340 151 | 239,859 -> 239,409 152 | 651,508 -> 314,845 153 | 720,39 -> 176,583 154 | 762,444 -> 762,29 155 | 983,962 -> 60,39 156 | 745,248 -> 91,902 157 | 990,18 -> 990,503 158 | 441,472 -> 441,211 159 | 524,837 -> 248,561 160 | 160,215 -> 842,897 161 | 469,544 -> 989,544 162 | 311,241 -> 103,33 163 | 887,610 -> 746,610 164 | 377,942 -> 377,803 165 | 920,401 -> 823,401 166 | 10,142 -> 10,486 167 | 850,955 -> 850,578 168 | 887,728 -> 887,678 169 | 555,749 -> 84,749 170 | 839,620 -> 32,620 171 | 432,709 -> 432,183 172 | 312,164 -> 859,711 173 | 20,119 -> 739,838 174 | 930,871 -> 324,265 175 | 41,702 -> 41,520 176 | 48,210 -> 794,956 177 | 479,526 -> 479,123 178 | 364,739 -> 364,379 179 | 920,969 -> 73,122 180 | 382,314 -> 382,604 181 | 969,877 -> 129,37 182 | 274,893 -> 52,671 183 | 696,296 -> 696,221 184 | 469,735 -> 626,892 185 | 682,435 -> 682,937 186 | 626,550 -> 626,604 187 | 898,904 -> 898,755 188 | 836,849 -> 445,458 189 | 405,237 -> 405,724 190 | 253,74 -> 908,729 191 | 837,802 -> 597,802 192 | 375,450 -> 316,450 193 | 621,784 -> 314,784 194 | 856,136 -> 188,804 195 | 983,11 -> 29,965 196 | 82,134 -> 752,134 197 | 677,299 -> 573,299 198 | 43,726 -> 43,304 199 | 886,629 -> 886,603 200 | 439,471 -> 74,836 201 | 973,879 -> 122,28 202 | 550,246 -> 497,246 203 | 49,109 -> 816,876 204 | 294,493 -> 271,493 205 | 495,397 -> 495,342 206 | 846,892 -> 881,927 207 | 267,397 -> 72,592 208 | 670,168 -> 22,816 209 | 482,302 -> 482,681 210 | 309,692 -> 453,692 211 | 597,369 -> 597,589 212 | 518,475 -> 633,475 213 | 391,484 -> 493,382 214 | 177,135 -> 139,135 215 | 458,17 -> 825,17 216 | 514,292 -> 272,50 217 | 410,734 -> 142,734 218 | 465,975 -> 542,898 219 | 32,901 -> 346,587 220 | 390,478 -> 571,659 221 | 835,839 -> 189,839 222 | 769,407 -> 769,788 223 | 974,40 -> 103,911 224 | 710,709 -> 246,709 225 | 468,857 -> 343,982 226 | 777,552 -> 951,552 227 | 23,490 -> 346,490 228 | 270,384 -> 855,384 229 | 386,454 -> 166,454 230 | 166,388 -> 319,388 231 | 698,514 -> 698,180 232 | 554,162 -> 528,162 233 | 651,363 -> 879,363 234 | 327,123 -> 327,255 235 | 439,492 -> 719,212 236 | 903,438 -> 903,356 237 | 99,611 -> 99,552 238 | 512,652 -> 45,185 239 | 565,284 -> 565,180 240 | 81,710 -> 637,154 241 | 321,769 -> 164,769 242 | 32,307 -> 32,204 243 | 310,338 -> 310,914 244 | 239,691 -> 357,691 245 | 573,164 -> 559,164 246 | 887,961 -> 693,767 247 | 362,904 -> 362,944 248 | 467,294 -> 236,294 249 | 182,53 -> 182,264 250 | 19,950 -> 951,18 251 | 191,575 -> 440,824 252 | 192,168 -> 690,666 253 | 538,552 -> 891,905 254 | 243,38 -> 243,403 255 | 417,140 -> 417,818 256 | 894,45 -> 726,213 257 | 245,898 -> 245,527 258 | 567,946 -> 567,983 259 | 572,675 -> 363,675 260 | 318,618 -> 735,618 261 | 616,580 -> 981,580 262 | 37,881 -> 134,881 263 | 624,675 -> 271,322 264 | 323,686 -> 770,686 265 | 93,385 -> 626,385 266 | 715,382 -> 862,382 267 | 170,342 -> 170,84 268 | 747,221 -> 380,221 269 | 981,311 -> 981,577 270 | 372,186 -> 372,826 271 | 961,91 -> 130,922 272 | 48,603 -> 48,110 273 | 34,975 -> 935,74 274 | 707,18 -> 707,192 275 | 261,149 -> 41,369 276 | 35,589 -> 35,247 277 | 544,522 -> 437,522 278 | 797,712 -> 346,712 279 | 622,47 -> 78,591 280 | 642,390 -> 642,414 281 | 793,29 -> 69,29 282 | 978,905 -> 978,296 283 | 212,515 -> 212,920 284 | 835,166 -> 68,933 285 | 168,742 -> 168,720 286 | 390,276 -> 666,276 287 | 507,792 -> 987,792 288 | 895,242 -> 895,402 289 | 121,950 -> 943,128 290 | 303,336 -> 303,205 291 | 293,390 -> 293,736 292 | 433,963 -> 433,867 293 | 824,327 -> 620,531 294 | 553,689 -> 867,689 295 | 226,984 -> 226,284 296 | 153,308 -> 173,308 297 | 855,959 -> 345,959 298 | 830,895 -> 830,981 299 | 557,63 -> 557,205 300 | 51,857 -> 328,857 301 | 224,243 -> 224,517 302 | 830,773 -> 830,520 303 | 607,210 -> 782,385 304 | 876,330 -> 327,330 305 | 985,11 -> 18,978 306 | 352,936 -> 111,936 307 | 900,39 -> 986,39 308 | 10,626 -> 10,795 309 | 369,942 -> 11,942 310 | 136,770 -> 654,252 311 | 209,541 -> 209,557 312 | 69,671 -> 848,671 313 | 811,451 -> 194,451 314 | 149,46 -> 850,747 315 | 704,386 -> 704,953 316 | 117,346 -> 387,346 317 | 238,701 -> 688,251 318 | 789,220 -> 789,815 319 | 967,512 -> 967,213 320 | 641,652 -> 151,162 321 | 91,942 -> 312,942 322 | 42,226 -> 801,985 323 | 166,37 -> 603,37 324 | 854,976 -> 951,976 325 | 392,23 -> 772,23 326 | 299,196 -> 299,288 327 | 514,560 -> 844,890 328 | 618,699 -> 348,429 329 | 604,947 -> 604,735 330 | 189,851 -> 407,633 331 | 907,719 -> 907,449 332 | 167,421 -> 864,421 333 | 491,383 -> 538,383 334 | 939,504 -> 939,433 335 | 78,649 -> 78,975 336 | 817,246 -> 322,741 337 | 395,195 -> 205,195 338 | 872,275 -> 872,500 339 | 196,621 -> 280,621 340 | 634,619 -> 634,422 341 | 395,30 -> 395,232 342 | 895,628 -> 619,904 343 | 58,66 -> 186,194 344 | 626,477 -> 708,559 345 | 747,712 -> 747,28 346 | 935,798 -> 220,798 347 | 459,530 -> 704,530 348 | 648,679 -> 79,110 349 | 778,135 -> 778,66 350 | 657,352 -> 906,352 351 | 499,160 -> 615,160 352 | 830,226 -> 830,489 353 | 364,971 -> 826,971 354 | 879,923 -> 543,923 355 | 914,984 -> 612,984 356 | 594,810 -> 508,810 357 | 55,467 -> 269,253 358 | 360,478 -> 360,902 359 | 176,890 -> 176,431 360 | 867,121 -> 16,972 361 | 728,876 -> 65,213 362 | 606,112 -> 842,112 363 | 563,532 -> 914,532 364 | 783,139 -> 369,139 365 | 564,359 -> 846,359 366 | 79,326 -> 15,390 367 | 972,419 -> 972,35 368 | 686,839 -> 755,839 369 | 427,856 -> 77,856 370 | 102,410 -> 925,410 371 | 468,177 -> 901,610 372 | 865,249 -> 930,314 373 | 784,447 -> 863,368 374 | 684,708 -> 223,708 375 | 555,228 -> 555,900 376 | 380,600 -> 222,600 377 | 900,408 -> 188,408 378 | 773,677 -> 773,16 379 | 560,287 -> 560,790 380 | 130,851 -> 959,22 381 | 338,951 -> 626,663 382 | 678,726 -> 405,726 383 | 243,469 -> 243,276 384 | 783,486 -> 66,486 385 | 469,536 -> 469,770 386 | 689,148 -> 689,340 387 | 396,689 -> 396,673 388 | 848,759 -> 848,770 389 | 965,775 -> 965,605 390 | 889,907 -> 284,302 391 | 161,169 -> 942,950 392 | 619,267 -> 394,492 393 | 323,786 -> 18,481 394 | 953,643 -> 884,643 395 | 371,446 -> 371,252 396 | 890,915 -> 192,217 397 | 674,259 -> 674,247 398 | 877,479 -> 877,117 399 | 620,843 -> 620,734 400 | 597,722 -> 597,939 401 | 935,663 -> 935,469 402 | 108,844 -> 108,596 403 | 211,447 -> 211,482 404 | 123,657 -> 721,59 405 | 774,858 -> 774,86 406 | 978,500 -> 978,305 407 | 152,890 -> 937,105 408 | 728,356 -> 728,261 409 | 354,373 -> 433,452 410 | 586,627 -> 586,949 411 | 764,381 -> 735,410 412 | 986,899 -> 199,112 413 | 251,418 -> 251,596 414 | 897,379 -> 897,388 415 | 149,901 -> 253,901 416 | 650,229 -> 46,229 417 | 446,707 -> 446,44 418 | 953,898 -> 697,898 419 | 772,422 -> 762,432 420 | 608,756 -> 927,756 421 | 138,911 -> 716,333 422 | 414,583 -> 244,583 423 | 219,267 -> 219,751 424 | 69,746 -> 69,886 425 | 444,243 -> 493,194 426 | 604,950 -> 244,950 427 | 450,198 -> 31,617 428 | 918,852 -> 109,43 429 | 967,800 -> 267,100 430 | 388,516 -> 760,516 431 | 656,954 -> 513,954 432 | 80,680 -> 80,44 433 | 360,848 -> 360,800 434 | 10,10 -> 989,989 435 | 889,927 -> 104,142 436 | 882,187 -> 812,187 437 | 416,522 -> 356,522 438 | 797,795 -> 273,271 439 | 175,371 -> 12,371 440 | 726,595 -> 956,595 441 | 852,355 -> 852,357 442 | 959,83 -> 338,83 443 | 822,766 -> 140,84 444 | 968,129 -> 181,916 445 | 17,28 -> 975,986 446 | 15,913 -> 624,304 447 | 589,322 -> 468,443 448 | 894,21 -> 309,606 449 | 83,25 -> 963,905 450 | 143,380 -> 377,146 451 | 587,151 -> 507,151 452 | 257,967 -> 257,882 453 | 770,552 -> 770,573 454 | 128,90 -> 886,848 455 | 456,953 -> 456,669 456 | 930,434 -> 668,434 457 | 501,835 -> 796,540 458 | 36,980 -> 989,27 459 | 494,690 -> 626,690 460 | 105,945 -> 972,78 461 | 409,730 -> 409,62 462 | 901,160 -> 831,90 463 | 881,490 -> 28,490 464 | 736,244 -> 38,942 465 | 295,770 -> 199,770 466 | 866,416 -> 808,416 467 | 875,716 -> 875,189 468 | 763,393 -> 241,915 469 | 583,237 -> 704,237 470 | 29,153 -> 637,153 471 | 767,282 -> 767,107 472 | 456,242 -> 456,165 473 | 455,232 -> 749,232 474 | 54,128 -> 766,840 475 | 901,73 -> 939,73 476 | 928,118 -> 854,118 477 | 15,983 -> 975,23 478 | 600,92 -> 260,92 479 | 247,714 -> 247,490 480 | 511,332 -> 19,824 481 | 55,15 -> 968,928 482 | 246,29 -> 25,29 483 | 22,101 -> 761,840 484 | 876,177 -> 139,914 485 | 165,150 -> 822,807 486 | 258,707 -> 773,707 487 | 68,788 -> 68,875 488 | 858,142 -> 758,142 489 | 719,642 -> 810,642 490 | 928,904 -> 928,338 491 | 287,977 -> 978,286 492 | 883,13 -> 883,31 493 | 681,301 -> 681,957 494 | 762,863 -> 405,506 495 | 194,657 -> 733,118 496 | 78,41 -> 497,41 497 | 840,627 -> 840,168 498 | 335,54 -> 335,822 499 | 136,983 -> 526,593 500 | 120,156 -> 120,630 501 | -------------------------------------------------------------------------------- /day-5-2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | if err := run(); err != nil { 12 | fmt.Fprintln(os.Stderr, err) 13 | os.Exit(1) 14 | } 15 | } 16 | 17 | func run() error { 18 | input, err := ioutil.ReadAll(os.Stdin) 19 | if err != nil { 20 | return err 21 | } 22 | answer, err := Answer(strings.TrimSpace(string(input)) + "\n") 23 | fmt.Printf("answer: %v\n", answer) 24 | return err 25 | } 26 | 27 | // See v*.go files for Answer() implementations. 28 | -------------------------------------------------------------------------------- /day-5-2/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | var exampleInput = strings.TrimSpace(` 12 | 0,9 -> 5,9 13 | 8,0 -> 0,8 14 | 9,4 -> 3,4 15 | 2,2 -> 2,1 16 | 7,0 -> 7,4 17 | 6,4 -> 2,0 18 | 0,9 -> 2,9 19 | 3,4 -> 1,4 20 | 0,0 -> 8,8 21 | 5,5 -> 8,2 22 | `) + "\n" 23 | 24 | var puzzleInput = (func() string { 25 | data, err := ioutil.ReadFile("./input.txt") 26 | if err != nil { 27 | panic(err) 28 | } 29 | return strings.TrimSpace(string(data)) + "\n" 30 | })() 31 | 32 | func TestGrid(t *testing.T) { 33 | t.Run("Get", func(t *testing.T) { 34 | g := NewGrid(3, 4) 35 | require.Equal(t, 0, g.Get(0, 0)) 36 | require.Equal(t, 0, g.Get(2, 3)) 37 | require.Panics(t, func() { 38 | g.Get(2, 4) 39 | }) 40 | require.Panics(t, func() { 41 | g.Get(3, 3) 42 | }) 43 | }) 44 | 45 | t.Run("Set", func(t *testing.T) { 46 | g := NewGrid(3, 4) 47 | g.Set(0, 0, 1) 48 | g.Set(2, 3, 2) 49 | require.Equal(t, 1, g.Get(0, 0)) 50 | require.Equal(t, 2, g.Get(2, 3)) 51 | }) 52 | 53 | t.Run("String", func(t *testing.T) { 54 | g := NewGrid(2, 3) 55 | require.Equal(t, "..\n..\n..", g.String()) 56 | g.Set(0, 0, 1) 57 | g.Set(0, 1, 2) 58 | g.Set(1, 2, 3) 59 | require.Equal(t, "1.\n2.\n.3", g.String()) 60 | }) 61 | } 62 | 63 | func BenchmarkGrid(b *testing.B) { 64 | g := NewGrid(10, 15) 65 | for i := 0; i < b.N; i++ { 66 | g.Set(i%10, i%15, i) 67 | _ = g.Get(i%10, i%15) 68 | } 69 | } 70 | 71 | func TestInput(t *testing.T) { 72 | t.Run("ParseInput", func(t *testing.T) { 73 | input, err := ParseInput(exampleInput) 74 | require.NoError(t, err) 75 | 76 | require.Equal(t, 0, input.lines[0].X1) 77 | require.Equal(t, 9, input.lines[0].Y1) 78 | require.Equal(t, 5, input.lines[0].X2) 79 | require.Equal(t, 9, input.lines[0].Y2) 80 | 81 | require.Equal(t, 5, input.lines[9].X1) 82 | require.Equal(t, 5, input.lines[9].Y1) 83 | require.Equal(t, 8, input.lines[9].X2) 84 | require.Equal(t, 2, input.lines[9].Y2) 85 | 86 | input, err = ParseInput(puzzleInput) 87 | require.NoError(t, err) 88 | require.Equal(t, 957, input.lines[0].X1) 89 | require.Equal(t, 596, input.lines[0].Y1) 90 | require.Equal(t, 957, input.lines[0].X2) 91 | require.Equal(t, 182, input.lines[0].Y2) 92 | }) 93 | 94 | t.Run("Grid", func(t *testing.T) { 95 | input, err := ParseInput(exampleInput) 96 | require.NoError(t, err) 97 | grid := input.Grid() 98 | want := strings.TrimSpace(` 99 | 1.1....11. 100 | .111...2.. 101 | ..2.1.111. 102 | ...1.2.2.. 103 | .112313211 104 | ...1.2.... 105 | ..1...1... 106 | .1.....1.. 107 | 1.......1. 108 | 222111.... 109 | `) 110 | require.Equal(t, want, grid.String()) 111 | }) 112 | } 113 | 114 | func TestAnswer(t *testing.T) { 115 | t.Run("example", func(t *testing.T) { 116 | answer, err := Answer(exampleInput) 117 | require.NoError(t, err) 118 | require.Equal(t, 12, answer) 119 | }) 120 | 121 | t.Run("puzzle", func(t *testing.T) { 122 | answer, err := Answer(puzzleInput) 123 | require.NoError(t, err) 124 | require.Equal(t, answer, 19929) 125 | }) 126 | } 127 | 128 | func BenchmarkAnswer(b *testing.B) { 129 | b.ReportAllocs() 130 | for i := 0; i < b.N; i++ { 131 | Answer(puzzleInput) 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /day-5-2/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-2/v1.cpu.pprof -------------------------------------------------------------------------------- /day-5-2/v1.go: -------------------------------------------------------------------------------- 1 | //go:build v1 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func Answer(inputText string) (int, error) { 12 | input, err := ParseInput(inputText) 13 | if err != nil { 14 | return 0, err 15 | } 16 | return input.Grid().Count(func(val int) bool { 17 | return val >= 2 18 | }), nil 19 | } 20 | 21 | func ParseInput(text string) (*Input, error) { 22 | // parser states 23 | const ( 24 | x1 = iota 25 | y1 26 | arrowSpace 27 | arrowDash 28 | arrowGt 29 | x2 30 | y2 31 | ) 32 | 33 | var ( 34 | input Input 35 | state = x1 36 | line Line 37 | ) 38 | 39 | for i := 0; i < len(text); i++ { 40 | c := text[i] 41 | switch state { 42 | case x1: 43 | if c >= '0' && c <= '9' { 44 | line.X1 = line.X1*10 + int(c) - '0' 45 | } else if c == ',' { 46 | state = y1 47 | } else { 48 | return nil, fmt.Errorf("x1: bad char: %q", string(c)) 49 | } 50 | case y1: 51 | if c >= '0' && c <= '9' { 52 | line.Y1 = line.Y1*10 + int(c) - '0' 53 | } else if c == ' ' { 54 | state = arrowSpace 55 | } else { 56 | return nil, fmt.Errorf("y1: bad char: %q", string(c)) 57 | } 58 | case arrowSpace: 59 | if c == '-' { 60 | state = arrowDash 61 | } else { 62 | return nil, fmt.Errorf("arrowSpace: bad char: %q", string(c)) 63 | } 64 | case arrowDash: 65 | if c == '>' { 66 | state = arrowGt 67 | } else { 68 | return nil, fmt.Errorf("arrowDash: bad char: %q", string(c)) 69 | } 70 | case arrowGt: 71 | if c == ' ' { 72 | state = x2 73 | } else { 74 | return nil, fmt.Errorf("arrowGt: bad char: %q", string(c)) 75 | } 76 | case x2: 77 | if c >= '0' && c <= '9' { 78 | line.X2 = line.X2*10 + int(c) - '0' 79 | } else if c == ',' { 80 | state = y2 81 | } else { 82 | return nil, fmt.Errorf("x2: bad char: %q", string(c)) 83 | } 84 | case y2: 85 | if c >= '0' && c <= '9' { 86 | line.Y2 = line.Y2*10 + int(c) - '0' 87 | } else if c == '\n' { 88 | input.lines = append(input.lines, line) 89 | line = Line{} 90 | state = x1 91 | } else { 92 | return nil, fmt.Errorf("y2: bad char: %q", string(c)) 93 | } 94 | } 95 | } 96 | return &input, nil 97 | } 98 | 99 | type Input struct { 100 | lines []Line 101 | } 102 | 103 | func (i *Input) Grid() Grid { 104 | var ( 105 | width = -1 106 | height = -1 107 | ) 108 | for _, l := range i.lines { 109 | if l.X1 > width { 110 | width = l.X1 111 | } 112 | if l.X2 > width { 113 | width = l.X2 114 | } 115 | if l.Y1 > height { 116 | height = l.Y1 117 | } 118 | if l.Y2 > height { 119 | height = l.Y2 120 | } 121 | } 122 | 123 | g := NewGrid(width+1, height+1) 124 | for _, l := range i.lines { 125 | x, y := l.X1, l.Y1 126 | for { 127 | g.Inc(x, y) 128 | if l.X1 < l.X2 { 129 | x++ 130 | if x > l.X2 { 131 | break 132 | } 133 | } else if l.X1 > l.X2 { 134 | x-- 135 | if x < l.X2 { 136 | break 137 | } 138 | } 139 | 140 | if l.Y1 < l.Y2 { 141 | y++ 142 | if y > l.Y2 { 143 | break 144 | } 145 | } else if l.Y1 > l.Y2 { 146 | y-- 147 | if y < l.Y2 { 148 | break 149 | } 150 | } 151 | } 152 | } 153 | 154 | return g 155 | } 156 | 157 | type Line struct { 158 | X1 int 159 | Y1 int 160 | X2 int 161 | Y2 int 162 | } 163 | 164 | func NewGrid(width, height int) Grid { 165 | return Grid{ 166 | data: make([]int, width*height), 167 | width: width, 168 | height: height, 169 | } 170 | } 171 | 172 | type Grid struct { 173 | data []int 174 | width int 175 | height int 176 | } 177 | 178 | func (g Grid) Get(x, y int) int { 179 | return g.data[g.offset(x, y)] 180 | } 181 | 182 | func (g Grid) Set(x, y, val int) { 183 | g.data[g.offset(x, y)] = val 184 | } 185 | 186 | func (g Grid) Inc(x, y int) { 187 | g.data[g.offset(x, y)]++ 188 | } 189 | 190 | func (g Grid) Count(fn func(val int) bool) (count int) { 191 | for _, v := range g.data { 192 | if fn(v) { 193 | count++ 194 | } 195 | } 196 | return 197 | } 198 | 199 | func (g Grid) offset(x, y int) int { 200 | return y*g.width + x 201 | } 202 | 203 | func (g Grid) String() string { 204 | var lines []string 205 | for y := 0; y < g.height; y++ { 206 | var line string 207 | for x := 0; x < g.width; x++ { 208 | val := g.Get(x, y) 209 | var char string 210 | if val == 0 { 211 | char = "." 212 | } else { 213 | char = strconv.Itoa(val) 214 | } 215 | line += char 216 | } 217 | lines = append(lines, line) 218 | } 219 | return strings.Join(lines, "\n") 220 | } 221 | -------------------------------------------------------------------------------- /day-5-2/v1.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-2/v1.mem.pprof -------------------------------------------------------------------------------- /day-5-2/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-5-2 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 254 4485180 ns/op 7888894 B/op 12 allocs/op 6 | BenchmarkAnswer-6 252 4429570 ns/op 7888890 B/op 12 allocs/op 7 | BenchmarkAnswer-6 262 4396741 ns/op 7888890 B/op 12 allocs/op 8 | BenchmarkAnswer-6 264 4385569 ns/op 7888911 B/op 12 allocs/op 9 | BenchmarkAnswer-6 256 4380488 ns/op 7888891 B/op 12 allocs/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-5-2 8.152s 12 | -------------------------------------------------------------------------------- /day-5-2/v2.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-2/v2.cpu.pprof -------------------------------------------------------------------------------- /day-5-2/v2.go: -------------------------------------------------------------------------------- 1 | //go:build v2 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func Answer(inputText string) (int, error) { 12 | input, err := ParseInput(inputText) 13 | if err != nil { 14 | return 0, err 15 | } 16 | return input.Grid().Count(func(val int) bool { 17 | return val >= 2 18 | }), nil 19 | } 20 | 21 | func ParseInput(text string) (*Input, error) { 22 | // parser states 23 | const ( 24 | x1 = iota 25 | y1 26 | arrowSpace 27 | arrowDash 28 | arrowGt 29 | x2 30 | y2 31 | ) 32 | 33 | var ( 34 | input Input 35 | state = x1 36 | line Line 37 | ) 38 | 39 | for i := 0; i < len(text); i++ { 40 | c := text[i] 41 | switch state { 42 | case x1: 43 | if c >= '0' && c <= '9' { 44 | line.X1 = line.X1*10 + int(c) - '0' 45 | } else if c == ',' { 46 | state = y1 47 | } else { 48 | return nil, fmt.Errorf("x1: bad char: %q", string(c)) 49 | } 50 | case y1: 51 | if c >= '0' && c <= '9' { 52 | line.Y1 = line.Y1*10 + int(c) - '0' 53 | } else if c == ' ' { 54 | state = arrowSpace 55 | } else { 56 | return nil, fmt.Errorf("y1: bad char: %q", string(c)) 57 | } 58 | case arrowSpace: 59 | if c == '-' { 60 | state = arrowDash 61 | } else { 62 | return nil, fmt.Errorf("arrowSpace: bad char: %q", string(c)) 63 | } 64 | case arrowDash: 65 | if c == '>' { 66 | state = arrowGt 67 | } else { 68 | return nil, fmt.Errorf("arrowDash: bad char: %q", string(c)) 69 | } 70 | case arrowGt: 71 | if c == ' ' { 72 | state = x2 73 | } else { 74 | return nil, fmt.Errorf("arrowGt: bad char: %q", string(c)) 75 | } 76 | case x2: 77 | if c >= '0' && c <= '9' { 78 | line.X2 = line.X2*10 + int(c) - '0' 79 | } else if c == ',' { 80 | state = y2 81 | } else { 82 | return nil, fmt.Errorf("x2: bad char: %q", string(c)) 83 | } 84 | case y2: 85 | if c >= '0' && c <= '9' { 86 | line.Y2 = line.Y2*10 + int(c) - '0' 87 | } else if c == '\n' { 88 | input.lines = append(input.lines, line) 89 | line = Line{} 90 | state = x1 91 | } else { 92 | return nil, fmt.Errorf("y2: bad char: %q", string(c)) 93 | } 94 | } 95 | } 96 | return &input, nil 97 | } 98 | 99 | type Input struct { 100 | lines []Line 101 | } 102 | 103 | func (i *Input) Grid() *Grid { 104 | var ( 105 | width = -1 106 | height = -1 107 | ) 108 | for _, l := range i.lines { 109 | if l.X1 > width { 110 | width = l.X1 111 | } 112 | if l.X2 > width { 113 | width = l.X2 114 | } 115 | if l.Y1 > height { 116 | height = l.Y1 117 | } 118 | if l.Y2 > height { 119 | height = l.Y2 120 | } 121 | } 122 | 123 | g := NewGrid(width+1, height+1) 124 | for _, l := range i.lines { 125 | x, y := l.X1, l.Y1 126 | for { 127 | g.Inc(x, y) 128 | if l.X1 < l.X2 { 129 | x++ 130 | if x > l.X2 { 131 | break 132 | } 133 | } else if l.X1 > l.X2 { 134 | x-- 135 | if x < l.X2 { 136 | break 137 | } 138 | } 139 | 140 | if l.Y1 < l.Y2 { 141 | y++ 142 | if y > l.Y2 { 143 | break 144 | } 145 | } else if l.Y1 > l.Y2 { 146 | y-- 147 | if y < l.Y2 { 148 | break 149 | } 150 | } 151 | } 152 | } 153 | 154 | return g 155 | } 156 | 157 | type Line struct { 158 | X1 int 159 | Y1 int 160 | X2 int 161 | Y2 int 162 | } 163 | 164 | func NewGrid(width, height int) *Grid { 165 | return &Grid{ 166 | data: make([]int, width*height), 167 | width: width, 168 | height: height, 169 | } 170 | } 171 | 172 | type Grid struct { 173 | data []int 174 | width int 175 | height int 176 | } 177 | 178 | func (g *Grid) Get(x, y int) int { 179 | return g.data[g.offset(x, y)] 180 | } 181 | 182 | func (g *Grid) Set(x, y, val int) { 183 | g.data[g.offset(x, y)] = val 184 | } 185 | 186 | func (g *Grid) Inc(x, y int) { 187 | g.data[g.offset(x, y)]++ 188 | } 189 | 190 | func (g *Grid) Count(fn func(val int) bool) (count int) { 191 | for _, v := range g.data { 192 | if fn(v) { 193 | count++ 194 | } 195 | } 196 | return 197 | } 198 | 199 | func (g *Grid) offset(x, y int) int { 200 | return y*g.width + x 201 | } 202 | 203 | func (g *Grid) String() string { 204 | var lines []string 205 | for y := 0; y < g.height; y++ { 206 | var line string 207 | for x := 0; x < g.width; x++ { 208 | val := g.Get(x, y) 209 | var char string 210 | if val == 0 { 211 | char = "." 212 | } else { 213 | char = strconv.Itoa(val) 214 | } 215 | line += char 216 | } 217 | lines = append(lines, line) 218 | } 219 | return strings.Join(lines, "\n") 220 | } 221 | -------------------------------------------------------------------------------- /day-5-2/v2.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-2/v2.mem.pprof -------------------------------------------------------------------------------- /day-5-2/v2.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-5-2 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 283 4081863 ns/op 7888960 B/op 13 allocs/op 6 | BenchmarkAnswer-6 280 4017210 ns/op 7888937 B/op 13 allocs/op 7 | BenchmarkAnswer-6 285 3972844 ns/op 7888937 B/op 13 allocs/op 8 | BenchmarkAnswer-6 285 3995427 ns/op 7888940 B/op 13 allocs/op 9 | BenchmarkAnswer-6 289 4013755 ns/op 7888937 B/op 13 allocs/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-5-2 7.954s 12 | -------------------------------------------------------------------------------- /day-5-2/v3.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-2/v3.cpu.pprof -------------------------------------------------------------------------------- /day-5-2/v3.go: -------------------------------------------------------------------------------- 1 | //go:build v3 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func Answer(inputText string) (int, error) { 12 | input, err := ParseInput(inputText) 13 | if err != nil { 14 | return 0, err 15 | } 16 | return input.Grid().Count(func(val int) int { 17 | if val >= 2 { 18 | return 1 19 | } 20 | return 0 21 | }), nil 22 | } 23 | 24 | func ParseInput(text string) (*Input, error) { 25 | // parser states 26 | const ( 27 | x1 = iota 28 | y1 29 | arrowSpace 30 | arrowDash 31 | arrowGt 32 | x2 33 | y2 34 | ) 35 | 36 | var ( 37 | input Input 38 | state = x1 39 | line Line 40 | ) 41 | 42 | for i := 0; i < len(text); i++ { 43 | c := text[i] 44 | switch state { 45 | case x1: 46 | if c >= '0' && c <= '9' { 47 | line.X1 = line.X1*10 + int(c) - '0' 48 | } else if c == ',' { 49 | state = y1 50 | } else { 51 | return nil, fmt.Errorf("x1: bad char: %q", string(c)) 52 | } 53 | case y1: 54 | if c >= '0' && c <= '9' { 55 | line.Y1 = line.Y1*10 + int(c) - '0' 56 | } else if c == ' ' { 57 | state = arrowSpace 58 | } else { 59 | return nil, fmt.Errorf("y1: bad char: %q", string(c)) 60 | } 61 | case arrowSpace: 62 | if c == '-' { 63 | state = arrowDash 64 | } else { 65 | return nil, fmt.Errorf("arrowSpace: bad char: %q", string(c)) 66 | } 67 | case arrowDash: 68 | if c == '>' { 69 | state = arrowGt 70 | } else { 71 | return nil, fmt.Errorf("arrowDash: bad char: %q", string(c)) 72 | } 73 | case arrowGt: 74 | if c == ' ' { 75 | state = x2 76 | } else { 77 | return nil, fmt.Errorf("arrowGt: bad char: %q", string(c)) 78 | } 79 | case x2: 80 | if c >= '0' && c <= '9' { 81 | line.X2 = line.X2*10 + int(c) - '0' 82 | } else if c == ',' { 83 | state = y2 84 | } else { 85 | return nil, fmt.Errorf("x2: bad char: %q", string(c)) 86 | } 87 | case y2: 88 | if c >= '0' && c <= '9' { 89 | line.Y2 = line.Y2*10 + int(c) - '0' 90 | } else if c == '\n' { 91 | input.lines = append(input.lines, line) 92 | line = Line{} 93 | state = x1 94 | } else { 95 | return nil, fmt.Errorf("y2: bad char: %q", string(c)) 96 | } 97 | } 98 | } 99 | return &input, nil 100 | } 101 | 102 | type Input struct { 103 | lines []Line 104 | } 105 | 106 | func (i *Input) Grid() *Grid { 107 | var ( 108 | width = -1 109 | height = -1 110 | ) 111 | for _, l := range i.lines { 112 | if l.X1 > width { 113 | width = l.X1 114 | } 115 | if l.X2 > width { 116 | width = l.X2 117 | } 118 | if l.Y1 > height { 119 | height = l.Y1 120 | } 121 | if l.Y2 > height { 122 | height = l.Y2 123 | } 124 | } 125 | 126 | g := NewGrid(width+1, height+1) 127 | for _, l := range i.lines { 128 | x, y := l.X1, l.Y1 129 | for { 130 | g.Inc(x, y) 131 | if l.X1 < l.X2 { 132 | x++ 133 | if x > l.X2 { 134 | break 135 | } 136 | } else if l.X1 > l.X2 { 137 | x-- 138 | if x < l.X2 { 139 | break 140 | } 141 | } 142 | 143 | if l.Y1 < l.Y2 { 144 | y++ 145 | if y > l.Y2 { 146 | break 147 | } 148 | } else if l.Y1 > l.Y2 { 149 | y-- 150 | if y < l.Y2 { 151 | break 152 | } 153 | } 154 | } 155 | } 156 | 157 | return g 158 | } 159 | 160 | type Line struct { 161 | X1 int 162 | Y1 int 163 | X2 int 164 | Y2 int 165 | } 166 | 167 | func NewGrid(width, height int) *Grid { 168 | return &Grid{ 169 | data: make([]int, width*height), 170 | width: width, 171 | height: height, 172 | } 173 | } 174 | 175 | type Grid struct { 176 | data []int 177 | width int 178 | height int 179 | } 180 | 181 | func (g *Grid) Get(x, y int) int { 182 | return g.data[g.offset(x, y)] 183 | } 184 | 185 | func (g *Grid) Set(x, y, val int) { 186 | g.data[g.offset(x, y)] = val 187 | } 188 | 189 | func (g *Grid) Inc(x, y int) { 190 | g.data[g.offset(x, y)]++ 191 | } 192 | 193 | func (g *Grid) Count(fn func(val int) int) (count int) { 194 | for i := 0; i < len(g.data); i++ { 195 | count += fn(g.data[i]) 196 | } 197 | return 198 | } 199 | 200 | func (g *Grid) offset(x, y int) int { 201 | return y*g.width + x 202 | } 203 | 204 | func (g *Grid) String() string { 205 | var lines []string 206 | for y := 0; y < g.height; y++ { 207 | var line string 208 | for x := 0; x < g.width; x++ { 209 | val := g.Get(x, y) 210 | var char string 211 | if val == 0 { 212 | char = "." 213 | } else { 214 | char = strconv.Itoa(val) 215 | } 216 | line += char 217 | } 218 | lines = append(lines, line) 219 | } 220 | return strings.Join(lines, "\n") 221 | } 222 | -------------------------------------------------------------------------------- /day-5-2/v3.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-2/v3.mem.pprof -------------------------------------------------------------------------------- /day-5-2/v3.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-5-2 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 392 2856376 ns/op 7888950 B/op 13 allocs/op 6 | BenchmarkAnswer-6 391 3296323 ns/op 7888937 B/op 13 allocs/op 7 | BenchmarkAnswer-6 373 3200438 ns/op 7888938 B/op 13 allocs/op 8 | BenchmarkAnswer-6 372 2955366 ns/op 7888960 B/op 13 allocs/op 9 | BenchmarkAnswer-6 391 2922008 ns/op 7888959 B/op 13 allocs/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-5-2 7.543s 12 | -------------------------------------------------------------------------------- /day-5-2/v4.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-2/v4.cpu.pprof -------------------------------------------------------------------------------- /day-5-2/v4.go: -------------------------------------------------------------------------------- 1 | //go:build v4 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func Answer(inputText string) (int, error) { 12 | input, err := ParseInput(inputText) 13 | if err != nil { 14 | return 0, err 15 | } 16 | return input.Grid().CountEqGt2(), nil 17 | } 18 | 19 | func ParseInput(text string) (*Input, error) { 20 | // parser states 21 | const ( 22 | x1 = iota 23 | y1 24 | arrowSpace 25 | arrowDash 26 | arrowGt 27 | x2 28 | y2 29 | ) 30 | 31 | var ( 32 | input Input 33 | state = x1 34 | line Line 35 | ) 36 | 37 | for i := 0; i < len(text); i++ { 38 | c := text[i] 39 | switch state { 40 | case x1: 41 | if c >= '0' && c <= '9' { 42 | line.X1 = line.X1*10 + int(c) - '0' 43 | } else if c == ',' { 44 | state = y1 45 | } else { 46 | return nil, fmt.Errorf("x1: bad char: %q", string(c)) 47 | } 48 | case y1: 49 | if c >= '0' && c <= '9' { 50 | line.Y1 = line.Y1*10 + int(c) - '0' 51 | } else if c == ' ' { 52 | state = arrowSpace 53 | } else { 54 | return nil, fmt.Errorf("y1: bad char: %q", string(c)) 55 | } 56 | case arrowSpace: 57 | if c == '-' { 58 | state = arrowDash 59 | } else { 60 | return nil, fmt.Errorf("arrowSpace: bad char: %q", string(c)) 61 | } 62 | case arrowDash: 63 | if c == '>' { 64 | state = arrowGt 65 | } else { 66 | return nil, fmt.Errorf("arrowDash: bad char: %q", string(c)) 67 | } 68 | case arrowGt: 69 | if c == ' ' { 70 | state = x2 71 | } else { 72 | return nil, fmt.Errorf("arrowGt: bad char: %q", string(c)) 73 | } 74 | case x2: 75 | if c >= '0' && c <= '9' { 76 | line.X2 = line.X2*10 + int(c) - '0' 77 | } else if c == ',' { 78 | state = y2 79 | } else { 80 | return nil, fmt.Errorf("x2: bad char: %q", string(c)) 81 | } 82 | case y2: 83 | if c >= '0' && c <= '9' { 84 | line.Y2 = line.Y2*10 + int(c) - '0' 85 | } else if c == '\n' { 86 | input.lines = append(input.lines, line) 87 | line = Line{} 88 | state = x1 89 | } else { 90 | return nil, fmt.Errorf("y2: bad char: %q", string(c)) 91 | } 92 | } 93 | } 94 | return &input, nil 95 | } 96 | 97 | type Input struct { 98 | lines []Line 99 | } 100 | 101 | func (i *Input) Grid() *Grid { 102 | var ( 103 | width = -1 104 | height = -1 105 | ) 106 | for _, l := range i.lines { 107 | if l.X1 > width { 108 | width = l.X1 109 | } 110 | if l.X2 > width { 111 | width = l.X2 112 | } 113 | if l.Y1 > height { 114 | height = l.Y1 115 | } 116 | if l.Y2 > height { 117 | height = l.Y2 118 | } 119 | } 120 | 121 | g := NewGrid(width+1, height+1) 122 | for _, l := range i.lines { 123 | x, y := l.X1, l.Y1 124 | for { 125 | g.Inc(x, y) 126 | if l.X1 < l.X2 { 127 | x++ 128 | if x > l.X2 { 129 | break 130 | } 131 | } else if l.X1 > l.X2 { 132 | x-- 133 | if x < l.X2 { 134 | break 135 | } 136 | } 137 | 138 | if l.Y1 < l.Y2 { 139 | y++ 140 | if y > l.Y2 { 141 | break 142 | } 143 | } else if l.Y1 > l.Y2 { 144 | y-- 145 | if y < l.Y2 { 146 | break 147 | } 148 | } 149 | } 150 | } 151 | 152 | return g 153 | } 154 | 155 | type Line struct { 156 | X1 int 157 | Y1 int 158 | X2 int 159 | Y2 int 160 | } 161 | 162 | func NewGrid(width, height int) *Grid { 163 | return &Grid{ 164 | data: make([]int, width*height), 165 | width: width, 166 | height: height, 167 | } 168 | } 169 | 170 | type Grid struct { 171 | data []int 172 | countEqGt2 int 173 | width int 174 | height int 175 | } 176 | 177 | func (g *Grid) Get(x, y int) int { 178 | return g.data[g.offset(x, y)] 179 | } 180 | 181 | func (g *Grid) Set(x, y, val int) { 182 | g.data[g.offset(x, y)] = val 183 | } 184 | 185 | func (g *Grid) Inc(x, y int) { 186 | val := g.Get(x, y) 187 | val++ 188 | g.Set(x, y, val) 189 | if val == 2 { 190 | g.countEqGt2++ 191 | } 192 | } 193 | 194 | func (g *Grid) CountEqGt2() int { 195 | return g.countEqGt2 196 | } 197 | 198 | func (g *Grid) offset(x, y int) int { 199 | return y*g.width + x 200 | } 201 | 202 | func (g *Grid) String() string { 203 | var lines []string 204 | for y := 0; y < g.height; y++ { 205 | var line string 206 | for x := 0; x < g.width; x++ { 207 | val := g.Get(x, y) 208 | var char string 209 | if val == 0 { 210 | char = "." 211 | } else { 212 | char = strconv.Itoa(val) 213 | } 214 | line += char 215 | } 216 | lines = append(lines, line) 217 | } 218 | return strings.Join(lines, "\n") 219 | } 220 | -------------------------------------------------------------------------------- /day-5-2/v4.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-2/v4.mem.pprof -------------------------------------------------------------------------------- /day-5-2/v4.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-5-2 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 470 2295654 ns/op 7888945 B/op 13 allocs/op 6 | BenchmarkAnswer-6 492 2241543 ns/op 7888946 B/op 13 allocs/op 7 | BenchmarkAnswer-6 483 2245047 ns/op 7888937 B/op 13 allocs/op 8 | BenchmarkAnswer-6 487 2245534 ns/op 7888949 B/op 13 allocs/op 9 | BenchmarkAnswer-6 478 2291512 ns/op 7888939 B/op 13 allocs/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-5-2 6.848s 12 | -------------------------------------------------------------------------------- /day-5-2/v5.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-2/v5.cpu.pprof -------------------------------------------------------------------------------- /day-5-2/v5.go: -------------------------------------------------------------------------------- 1 | //go:build v5 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func Answer(inputText string) (int, error) { 12 | input, err := ParseInput(inputText) 13 | if err != nil { 14 | return 0, err 15 | } 16 | return input.Grid().CountEqGt2(), nil 17 | } 18 | 19 | func ParseInput(text string) (*Input, error) { 20 | // parser states 21 | const ( 22 | x1 = iota 23 | y1 24 | arrowSpace 25 | arrowDash 26 | arrowGt 27 | x2 28 | y2 29 | ) 30 | 31 | var ( 32 | input Input 33 | state = x1 34 | line Line 35 | ) 36 | 37 | for i := 0; i < len(text); i++ { 38 | c := text[i] 39 | switch state { 40 | case x1: 41 | if c >= '0' && c <= '9' { 42 | line.X1 = line.X1*10 + int(c) - '0' 43 | } else if c == ',' { 44 | state = y1 45 | } else { 46 | return nil, fmt.Errorf("x1: bad char: %q", string(c)) 47 | } 48 | case y1: 49 | if c >= '0' && c <= '9' { 50 | line.Y1 = line.Y1*10 + int(c) - '0' 51 | } else if c == ' ' { 52 | state = arrowSpace 53 | } else { 54 | return nil, fmt.Errorf("y1: bad char: %q", string(c)) 55 | } 56 | case arrowSpace: 57 | if c == '-' { 58 | state = arrowDash 59 | } else { 60 | return nil, fmt.Errorf("arrowSpace: bad char: %q", string(c)) 61 | } 62 | case arrowDash: 63 | if c == '>' { 64 | state = arrowGt 65 | } else { 66 | return nil, fmt.Errorf("arrowDash: bad char: %q", string(c)) 67 | } 68 | case arrowGt: 69 | if c == ' ' { 70 | state = x2 71 | } else { 72 | return nil, fmt.Errorf("arrowGt: bad char: %q", string(c)) 73 | } 74 | case x2: 75 | if c >= '0' && c <= '9' { 76 | line.X2 = line.X2*10 + int(c) - '0' 77 | } else if c == ',' { 78 | state = y2 79 | } else { 80 | return nil, fmt.Errorf("x2: bad char: %q", string(c)) 81 | } 82 | case y2: 83 | if c >= '0' && c <= '9' { 84 | line.Y2 = line.Y2*10 + int(c) - '0' 85 | } else if c == '\n' { 86 | input.lines = append(input.lines, line) 87 | line = Line{} 88 | state = x1 89 | } else { 90 | return nil, fmt.Errorf("y2: bad char: %q", string(c)) 91 | } 92 | } 93 | } 94 | return &input, nil 95 | } 96 | 97 | type Input struct { 98 | lines []Line 99 | } 100 | 101 | func (i *Input) Grid() *Grid { 102 | var ( 103 | width = -1 104 | height = -1 105 | ) 106 | for _, l := range i.lines { 107 | if l.X1 > width { 108 | width = l.X1 109 | } 110 | if l.X2 > width { 111 | width = l.X2 112 | } 113 | if l.Y1 > height { 114 | height = l.Y1 115 | } 116 | if l.Y2 > height { 117 | height = l.Y2 118 | } 119 | } 120 | 121 | g := NewGrid(width+1, height+1) 122 | for _, l := range i.lines { 123 | x, y := l.X1, l.Y1 124 | for { 125 | g.Inc(x, y) 126 | if l.X1 < l.X2 { 127 | x++ 128 | if x > l.X2 { 129 | break 130 | } 131 | } else if l.X1 > l.X2 { 132 | x-- 133 | if x < l.X2 { 134 | break 135 | } 136 | } 137 | 138 | if l.Y1 < l.Y2 { 139 | y++ 140 | if y > l.Y2 { 141 | break 142 | } 143 | } else if l.Y1 > l.Y2 { 144 | y-- 145 | if y < l.Y2 { 146 | break 147 | } 148 | } 149 | } 150 | } 151 | return g 152 | } 153 | 154 | type Line struct { 155 | X1 int 156 | Y1 int 157 | X2 int 158 | Y2 int 159 | } 160 | 161 | func NewGrid(width, height int) *Grid { 162 | return &Grid{ 163 | data: make([]int8, width*height), 164 | width: width, 165 | height: height, 166 | } 167 | } 168 | 169 | type Grid struct { 170 | data []int8 171 | countEqGt2 int 172 | width int 173 | height int 174 | } 175 | 176 | func (g *Grid) Get(x, y int) int { 177 | return int(g.data[g.offset(x, y)]) 178 | } 179 | 180 | func (g *Grid) Set(x, y, val int) { 181 | g.data[g.offset(x, y)] = int8(val) 182 | } 183 | 184 | func (g *Grid) Inc(x, y int) { 185 | val := g.data[g.offset(x, y)] 186 | val++ 187 | g.data[g.offset(x, y)] = val 188 | if val == 2 { 189 | g.countEqGt2++ 190 | } 191 | } 192 | 193 | func (g *Grid) CountEqGt2() int { 194 | return g.countEqGt2 195 | } 196 | 197 | func (g *Grid) offset(x, y int) int { 198 | return y*g.width + x 199 | } 200 | 201 | func (g *Grid) String() string { 202 | var lines []string 203 | for y := 0; y < g.height; y++ { 204 | var line string 205 | for x := 0; x < g.width; x++ { 206 | val := g.Get(x, y) 207 | var char string 208 | if val == 0 { 209 | char = "." 210 | } else { 211 | char = strconv.Itoa(int(val)) 212 | } 213 | line += char 214 | } 215 | lines = append(lines, line) 216 | } 217 | return strings.Join(lines, "\n") 218 | } 219 | -------------------------------------------------------------------------------- /day-5-2/v5.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-2/v5.mem.pprof -------------------------------------------------------------------------------- /day-5-2/v5.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-5-2 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 1700 715066 ns/op 1015853 B/op 13 allocs/op 6 | BenchmarkAnswer-6 1452 711016 ns/op 1015851 B/op 13 allocs/op 7 | BenchmarkAnswer-6 1696 705617 ns/op 1015855 B/op 13 allocs/op 8 | BenchmarkAnswer-6 1510 702377 ns/op 1015850 B/op 13 allocs/op 9 | BenchmarkAnswer-6 1435 707667 ns/op 1015852 B/op 13 allocs/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-5-2 8.034s 12 | -------------------------------------------------------------------------------- /day-5-2/v6.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-2/v6.cpu.pprof -------------------------------------------------------------------------------- /day-5-2/v6.go: -------------------------------------------------------------------------------- 1 | //go:build v6 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func Answer(inputText string) (int, error) { 12 | input, err := ParseInput(inputText) 13 | if err != nil { 14 | return 0, err 15 | } 16 | return input.Grid().CountEqGt2(), nil 17 | } 18 | 19 | func ParseInput(text string) (*Input, error) { 20 | // parser states 21 | const ( 22 | x1 = iota 23 | y1 24 | arrowSpace 25 | arrowDash 26 | arrowGt 27 | x2 28 | y2 29 | ) 30 | 31 | var ( 32 | input Input 33 | state = x1 34 | line Line 35 | ) 36 | 37 | for i := 0; i < len(text); i++ { 38 | c := text[i] 39 | switch state { 40 | case x1: 41 | if c >= '0' && c <= '9' { 42 | line.X1 = line.X1*10 + int(c) - '0' 43 | } else if c == ',' { 44 | state = y1 45 | } else { 46 | return nil, fmt.Errorf("x1: bad char: %q", string(c)) 47 | } 48 | case y1: 49 | if c >= '0' && c <= '9' { 50 | line.Y1 = line.Y1*10 + int(c) - '0' 51 | } else if c == ' ' { 52 | state = arrowSpace 53 | } else { 54 | return nil, fmt.Errorf("y1: bad char: %q", string(c)) 55 | } 56 | case arrowSpace: 57 | if c == '-' { 58 | state = arrowDash 59 | } else { 60 | return nil, fmt.Errorf("arrowSpace: bad char: %q", string(c)) 61 | } 62 | case arrowDash: 63 | if c == '>' { 64 | state = arrowGt 65 | } else { 66 | return nil, fmt.Errorf("arrowDash: bad char: %q", string(c)) 67 | } 68 | case arrowGt: 69 | if c == ' ' { 70 | state = x2 71 | } else { 72 | return nil, fmt.Errorf("arrowGt: bad char: %q", string(c)) 73 | } 74 | case x2: 75 | if c >= '0' && c <= '9' { 76 | line.X2 = line.X2*10 + int(c) - '0' 77 | } else if c == ',' { 78 | state = y2 79 | } else { 80 | return nil, fmt.Errorf("x2: bad char: %q", string(c)) 81 | } 82 | case y2: 83 | if c >= '0' && c <= '9' { 84 | line.Y2 = line.Y2*10 + int(c) - '0' 85 | } else if c == '\n' { 86 | input.lines = append(input.lines, line) 87 | line = Line{} 88 | state = x1 89 | } else { 90 | return nil, fmt.Errorf("y2: bad char: %q", string(c)) 91 | } 92 | } 93 | } 94 | return &input, nil 95 | } 96 | 97 | type Input struct { 98 | lines []Line 99 | } 100 | 101 | func (i *Input) Grid() *Grid { 102 | var ( 103 | width = -1 104 | height = -1 105 | ) 106 | for _, l := range i.lines { 107 | if l.X1 > width { 108 | width = l.X1 109 | } 110 | if l.X2 > width { 111 | width = l.X2 112 | } 113 | if l.Y1 > height { 114 | height = l.Y1 115 | } 116 | if l.Y2 > height { 117 | height = l.Y2 118 | } 119 | } 120 | 121 | g := NewGrid(width+1, height+1) 122 | for _, l := range i.lines { 123 | x, y := l.X1, l.Y1 124 | for { 125 | g.Inc(x, y) 126 | if l.X1 < l.X2 { 127 | x++ 128 | if x > l.X2 { 129 | break 130 | } 131 | } else if l.X1 > l.X2 { 132 | x-- 133 | if x < l.X2 { 134 | break 135 | } 136 | } 137 | 138 | if l.Y1 < l.Y2 { 139 | y++ 140 | if y > l.Y2 { 141 | break 142 | } 143 | } else if l.Y1 > l.Y2 { 144 | y-- 145 | if y < l.Y2 { 146 | break 147 | } 148 | } 149 | } 150 | } 151 | return g 152 | } 153 | 154 | type Line struct { 155 | X1 int 156 | Y1 int 157 | X2 int 158 | Y2 int 159 | } 160 | 161 | func NewGrid(width, height int) *Grid { 162 | return &Grid{ 163 | data: make([]uint8, (width*height+(4-1))/4), // 2 bit per item (ceil int division) 164 | width: width, 165 | height: height, 166 | } 167 | } 168 | 169 | type Grid struct { 170 | data []uint8 171 | countEqGt2 int 172 | width int 173 | height int 174 | } 175 | 176 | func (g *Grid) Get(x, y int) int { 177 | if x > g.width || y > g.height { 178 | panic("out of bounds") 179 | } 180 | return int(g.get(x, y)) 181 | } 182 | 183 | func (g *Grid) get(x, y int) uint8 { 184 | offset, shift := g.offset(x, y) 185 | return (g.data[offset] >> shift) & 3 186 | } 187 | 188 | func (g *Grid) Set(x, y, val int) { 189 | g.set(x, y, uint8(val)) 190 | } 191 | 192 | func (g *Grid) set(x, y int, val uint8) { 193 | offset, shift := g.offset(x, y) 194 | v := g.data[offset] 195 | v &^= (3 << shift) 196 | v |= (val << shift) 197 | g.data[offset] = v 198 | } 199 | 200 | func (g *Grid) Inc(x, y int) { 201 | offset, shift := g.offset(x, y) 202 | slotVal := g.data[offset] 203 | newVal := ((slotVal >> shift) & 3) + 1 204 | if newVal > 3 { 205 | return 206 | } 207 | slotVal &^= (3 << shift) 208 | slotVal |= (newVal << shift) 209 | g.data[offset] = slotVal 210 | if newVal == 2 { 211 | g.countEqGt2++ 212 | } 213 | } 214 | 215 | func (g *Grid) CountEqGt2() int { 216 | return g.countEqGt2 217 | } 218 | 219 | // 3x2 grid example 220 | // 221 | // x: 0 1 2 0 1 2 - - 222 | // y: 0 0 0 1 1 2 - - 223 | // index: 0 0 0 0 1 1 - - 224 | // shift: 6 4 2 0 6 4 - - 225 | // data: [00 00 00 00] [00 00 00 00] 226 | 227 | func (g *Grid) offset(x, y int) (int, uint8) { 228 | i := (y*g.width + x) 229 | return i / 4, 6 - uint8(i)%4*2 230 | } 231 | 232 | func (g *Grid) String() string { 233 | var lines []string 234 | for y := 0; y < g.height; y++ { 235 | var line string 236 | for x := 0; x < g.width; x++ { 237 | val := g.Get(x, y) 238 | var char string 239 | if val == 0 { 240 | char = "." 241 | } else { 242 | char = strconv.Itoa(int(val)) 243 | } 244 | line += char 245 | } 246 | lines = append(lines, line) 247 | } 248 | return strings.Join(lines, "\n") 249 | } 250 | -------------------------------------------------------------------------------- /day-5-2/v6.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-5-2/v6.mem.pprof -------------------------------------------------------------------------------- /day-5-2/v6.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-5-2 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 898 1229669 ns/op 278575 B/op 13 allocs/op 6 | BenchmarkAnswer-6 910 1215568 ns/op 278568 B/op 13 allocs/op 7 | BenchmarkAnswer-6 926 1227087 ns/op 278568 B/op 13 allocs/op 8 | BenchmarkAnswer-6 900 1241214 ns/op 278568 B/op 13 allocs/op 9 | BenchmarkAnswer-6 868 1235634 ns/op 278568 B/op 13 allocs/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-5-2 6.343s 12 | -------------------------------------------------------------------------------- /day-6-1/day-6-1.test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-6-1/day-6-1.test -------------------------------------------------------------------------------- /day-6-1/input.txt: -------------------------------------------------------------------------------- 1 | 1,1,1,3,3,2,1,1,1,1,1,4,4,1,4,1,4,1,1,4,1,1,1,3,3,2,3,1,2,1,1,1,1,1,1,1,3,4,1,1,4,3,1,2,3,1,1,1,5,2,1,1,1,1,2,1,2,5,2,2,1,1,1,3,1,1,1,4,1,1,1,1,1,3,3,2,1,1,3,1,4,1,2,1,5,1,4,2,1,1,5,1,1,1,1,4,3,1,3,2,1,4,1,1,2,1,4,4,5,1,3,1,1,1,1,2,1,4,4,1,1,1,3,1,5,1,1,1,1,1,3,2,5,1,5,4,1,4,1,3,5,1,2,5,4,3,3,2,4,1,5,1,1,2,4,1,1,1,1,2,4,1,2,5,1,4,1,4,2,5,4,1,1,2,2,4,1,5,1,4,3,3,2,3,1,2,3,1,4,1,1,1,3,5,1,1,1,3,5,1,1,4,1,4,4,1,3,1,1,1,2,3,3,2,5,1,2,1,1,2,2,1,3,4,1,3,5,1,3,4,3,5,1,1,5,1,3,3,2,1,5,1,1,3,1,1,3,1,2,1,3,2,5,1,3,1,1,3,5,1,1,1,1,2,1,2,4,4,4,2,2,3,1,5,1,2,1,3,3,3,4,1,1,5,1,3,2,4,1,5,5,1,4,4,1,4,4,1,1,2 2 | -------------------------------------------------------------------------------- /day-6-1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | if err := run(); err != nil { 12 | fmt.Fprintln(os.Stderr, err) 13 | os.Exit(1) 14 | } 15 | } 16 | 17 | func run() error { 18 | input, err := ioutil.ReadAll(os.Stdin) 19 | if err != nil { 20 | return err 21 | } 22 | answer, err := Answer(strings.TrimSpace(string(input)) + "\n") 23 | fmt.Printf("answer: %v\n", answer) 24 | return err 25 | } 26 | 27 | // See v*.go files for Answer() implementations. 28 | -------------------------------------------------------------------------------- /day-6-1/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | var exampleInput = strings.TrimSpace(` 12 | 3,4,3,1,2 13 | `) + "\n" 14 | 15 | var puzzleInput = (func() string { 16 | data, err := ioutil.ReadFile("./input.txt") 17 | if err != nil { 18 | panic(err) 19 | } 20 | return strings.TrimSpace(string(data)) + "\n" 21 | })() 22 | 23 | func TestAnswer(t *testing.T) { 24 | t.Run("example", func(t *testing.T) { 25 | answer, err := Answer(exampleInput) 26 | require.NoError(t, err) 27 | require.Equal(t, 5934, answer) 28 | }) 29 | 30 | t.Run("puzzle", func(t *testing.T) { 31 | answer, err := Answer(puzzleInput) 32 | require.NoError(t, err) 33 | require.Equal(t, answer, 372984) 34 | }) 35 | } 36 | 37 | func BenchmarkAnswer(b *testing.B) { 38 | b.ReportAllocs() 39 | for i := 0; i < b.N; i++ { 40 | Answer(puzzleInput) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /day-6-1/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-6-1/v1.cpu.pprof -------------------------------------------------------------------------------- /day-6-1/v1.go: -------------------------------------------------------------------------------- 1 | //go:build v1 2 | 3 | package main 4 | 5 | import ( 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | func Answer(inputText string) (int, error) { 11 | var school []int 12 | for _, ageS := range strings.Split(strings.TrimSpace(inputText), ",") { 13 | age, err := strconv.Atoi(ageS) 14 | if err != nil { 15 | return 0, err 16 | } 17 | school = append(school, age) 18 | } 19 | 20 | for i := 0; i < 80; i++ { 21 | for i, age := range school { 22 | school[i]-- 23 | if age == 0 { 24 | school[i] = 6 25 | school = append(school, 8) 26 | } 27 | } 28 | } 29 | return len(school), nil 30 | } 31 | -------------------------------------------------------------------------------- /day-6-1/v1.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-6-1/v1.mem.pprof -------------------------------------------------------------------------------- /day-6-1/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-6-1 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 168 6061741 ns/op 18356237 B/op 37 allocs/op 6 | BenchmarkAnswer-6 180 6110067 ns/op 18356227 B/op 37 allocs/op 7 | BenchmarkAnswer-6 182 6129553 ns/op 18356231 B/op 37 allocs/op 8 | BenchmarkAnswer-6 182 6187012 ns/op 18356225 B/op 37 allocs/op 9 | BenchmarkAnswer-6 181 6158288 ns/op 18356229 B/op 37 allocs/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-6-1 8.642s 12 | -------------------------------------------------------------------------------- /day-6-2/day-6-2.test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-6-2/day-6-2.test -------------------------------------------------------------------------------- /day-6-2/input.txt: -------------------------------------------------------------------------------- 1 | 1,1,1,3,3,2,1,1,1,1,1,4,4,1,4,1,4,1,1,4,1,1,1,3,3,2,3,1,2,1,1,1,1,1,1,1,3,4,1,1,4,3,1,2,3,1,1,1,5,2,1,1,1,1,2,1,2,5,2,2,1,1,1,3,1,1,1,4,1,1,1,1,1,3,3,2,1,1,3,1,4,1,2,1,5,1,4,2,1,1,5,1,1,1,1,4,3,1,3,2,1,4,1,1,2,1,4,4,5,1,3,1,1,1,1,2,1,4,4,1,1,1,3,1,5,1,1,1,1,1,3,2,5,1,5,4,1,4,1,3,5,1,2,5,4,3,3,2,4,1,5,1,1,2,4,1,1,1,1,2,4,1,2,5,1,4,1,4,2,5,4,1,1,2,2,4,1,5,1,4,3,3,2,3,1,2,3,1,4,1,1,1,3,5,1,1,1,3,5,1,1,4,1,4,4,1,3,1,1,1,2,3,3,2,5,1,2,1,1,2,2,1,3,4,1,3,5,1,3,4,3,5,1,1,5,1,3,3,2,1,5,1,1,3,1,1,3,1,2,1,3,2,5,1,3,1,1,3,5,1,1,1,1,2,1,2,4,4,4,2,2,3,1,5,1,2,1,3,3,3,4,1,1,5,1,3,2,4,1,5,5,1,4,4,1,4,4,1,1,2 2 | -------------------------------------------------------------------------------- /day-6-2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | if err := run(); err != nil { 12 | fmt.Fprintln(os.Stderr, err) 13 | os.Exit(1) 14 | } 15 | } 16 | 17 | func run() error { 18 | input, err := ioutil.ReadAll(os.Stdin) 19 | if err != nil { 20 | return err 21 | } 22 | answer, err := Answer(strings.TrimSpace(string(input)) + "\n") 23 | fmt.Printf("answer: %v\n", answer) 24 | return err 25 | } 26 | 27 | // See v*.go files for Answer() implementations. 28 | -------------------------------------------------------------------------------- /day-6-2/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | var exampleInput = strings.TrimSpace(` 12 | 3,4,3,1,2 13 | `) + "\n" 14 | 15 | var puzzleInput = (func() string { 16 | data, err := ioutil.ReadFile("./input.txt") 17 | if err != nil { 18 | panic(err) 19 | } 20 | return strings.TrimSpace(string(data)) + "\n" 21 | })() 22 | 23 | func TestAnswer(t *testing.T) { 24 | t.Run("example", func(t *testing.T) { 25 | answer, err := Answer(exampleInput) 26 | require.NoError(t, err) 27 | require.Equal(t, 26984457539, answer) 28 | }) 29 | 30 | t.Run("puzzle", func(t *testing.T) { 31 | answer, err := Answer(puzzleInput) 32 | require.NoError(t, err) 33 | require.Equal(t, answer, 1681503251694) 34 | }) 35 | } 36 | 37 | func BenchmarkAnswer(b *testing.B) { 38 | b.ReportAllocs() 39 | for i := 0; i < b.N; i++ { 40 | Answer(puzzleInput) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /day-6-2/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-6-2/v1.cpu.pprof -------------------------------------------------------------------------------- /day-6-2/v1.go: -------------------------------------------------------------------------------- 1 | //go:build v1 2 | 3 | package main 4 | 5 | import ( 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | func Answer(inputText string) (int, error) { 11 | school := make([]int, 9) 12 | for _, ageS := range strings.Split(strings.TrimSpace(inputText), ",") { 13 | age, err := strconv.Atoi(ageS) 14 | if err != nil { 15 | return 0, err 16 | } 17 | school[age]++ 18 | } 19 | 20 | for i := 0; i < 256; i++ { 21 | newFish := school[0] 22 | copy(school, school[1:]) 23 | school[6] += newFish 24 | school[8] = newFish 25 | } 26 | var total int 27 | for _, count := range school { 28 | total += count 29 | } 30 | return total, nil 31 | } 32 | -------------------------------------------------------------------------------- /day-6-2/v1.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felixge/advent-2021/5982f15a1a1ca2ad2be19443f391700d5e98a2a7/day-6-2/v1.mem.pprof -------------------------------------------------------------------------------- /day-6-2/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/felixge/advent-2021/day-6-2 4 | cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 5 | BenchmarkAnswer-6 182076 6669 ns/op 4864 B/op 1 allocs/op 6 | BenchmarkAnswer-6 165488 6692 ns/op 4864 B/op 1 allocs/op 7 | BenchmarkAnswer-6 165618 6651 ns/op 4864 B/op 1 allocs/op 8 | BenchmarkAnswer-6 174398 6629 ns/op 4864 B/op 1 allocs/op 9 | BenchmarkAnswer-6 179724 6617 ns/op 4864 B/op 1 allocs/op 10 | PASS 11 | ok github.com/felixge/advent-2021/day-6-2 8.248s 12 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/felixge/advent-2021 2 | 3 | go 1.17 4 | 5 | require github.com/matryer/is v1.4.0 6 | 7 | require ( 8 | github.com/davecgh/go-spew v1.1.0 // indirect 9 | github.com/pmezard/go-difflib v1.0.0 // indirect 10 | github.com/stretchr/testify v1.7.0 // indirect 11 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect 12 | ) 13 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= 4 | github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= 5 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 6 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 7 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 8 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 9 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 10 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 11 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 12 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 13 | --------------------------------------------------------------------------------