├── day1 └── sorry, I was too lazy and started with day2.txt ├── day2 ├── v1.cpu.pprof ├── v2.cpu.pprof ├── v3.cpu.pprof ├── v3.mem.pprof ├── v4.cpu.pprof ├── v4.mem.pprof ├── v5.cpu.pprof ├── v5.mem.pprof ├── v1.txt ├── v2.txt ├── v3.txt ├── v4.txt ├── v5.txt ├── main_test.go ├── main.go └── input.txt ├── day3 ├── v1.cpu.pprof ├── v1.mem.pprof ├── v2.cpu.pprof ├── v2.mem.pprof ├── v1.txt ├── v2.txt ├── main_test.go ├── main.go └── input.txt ├── day4 ├── v1.cpu.pprof ├── v1.mem.pprof ├── v2.cpu.pprof ├── v2.mem.pprof ├── v3.cpu.pprof ├── v3.mem.pprof ├── v4.cpu.pprof ├── v4.mem.pprof ├── v5.cpu.pprof ├── v5.mem.pprof ├── v3-2.cpu.pprof ├── v3-2.mem.pprof ├── v5-10workers.cpu.pprof ├── v5-10workers.mem.pprof ├── v5-2workers.cpu.pprof ├── v5-2workers.mem.pprof ├── v5-4workers.cpu.pprof ├── v5-4workers.mem.pprof ├── v5-1workers2proc.cpu.pprof ├── v5-1workers2proc.mem.pprof ├── v5-2workers1proc.cpu.pprof ├── v5-2workers1proc.mem.pprof ├── v5-5workers1proc.cpu.pprof ├── v5-5workers1proc.mem.pprof ├── v5-5workers2proc.cpu.pprof ├── v5-5workers2proc.mem.pprof ├── v5-5workers3proc.cpu.pprof ├── v5-5workers3proc.mem.pprof ├── v1.txt ├── v2.txt ├── v3.txt ├── v3-2.txt ├── v4.txt ├── v5.txt ├── v5-2workers.txt ├── v5-4workers.txt ├── v5-10workers.txt ├── v5-1workers2proc.txt ├── v5-2workers1proc.txt ├── v5-5workers1proc.txt ├── v5-5workers2proc.txt ├── v5-5workers3proc.txt ├── main_test.go └── input.txt ├── day5 ├── v1.cpu.pprof ├── v1.mem.pprof ├── v2.cpu.pprof ├── v2.mem.pprof ├── v3.cpu.pprof ├── v3.mem.pprof ├── v4.cpu.pprof ├── v4.mem.pprof ├── v5.cpu.pprof ├── v5.mem.pprof ├── v1.txt ├── v2.txt ├── v3.txt ├── v4.txt ├── v5.txt ├── main_test.go ├── input.txt └── main.go ├── day6 ├── v1.cpu.pprof ├── v1.mem.pprof ├── v2.cpu.pprof ├── v2.mem.pprof ├── v3.cpu.pprof ├── v3.mem.pprof ├── v4.cpu.pprof ├── v4.mem.pprof ├── v5.cpu.pprof ├── v5.mem.pprof ├── v2-2.cpu.pprof ├── v2-2.mem.pprof ├── v2-80.cpu.pprof ├── v2-80.mem.pprof ├── input.txt ├── v1.txt ├── v2.txt ├── v3.txt ├── v2-2.txt ├── v2-80.txt ├── v4.txt ├── v5.txt ├── main_test.go └── main.go ├── day7 ├── v1.cpu.pprof ├── v1.mem.pprof ├── v2.cpu.pprof ├── v2.mem.pprof ├── v1.txt ├── v2.txt ├── main_test.go ├── main.go └── input.txt ├── day19 ├── v1.cpu.pprof ├── v1.mem.pprof ├── v1.txt ├── main_test.go ├── main.go └── input.txt ├── .gitignore ├── go.mod ├── README.md ├── go.sum └── LICENSE /day1/sorry, I was too lazy and started with day2.txt: -------------------------------------------------------------------------------- 1 | Please read filename (: -------------------------------------------------------------------------------- /day2/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day2/v1.cpu.pprof -------------------------------------------------------------------------------- /day2/v2.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day2/v2.cpu.pprof -------------------------------------------------------------------------------- /day2/v3.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day2/v3.cpu.pprof -------------------------------------------------------------------------------- /day2/v3.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day2/v3.mem.pprof -------------------------------------------------------------------------------- /day2/v4.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day2/v4.cpu.pprof -------------------------------------------------------------------------------- /day2/v4.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day2/v4.mem.pprof -------------------------------------------------------------------------------- /day2/v5.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day2/v5.cpu.pprof -------------------------------------------------------------------------------- /day2/v5.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day2/v5.mem.pprof -------------------------------------------------------------------------------- /day3/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day3/v1.cpu.pprof -------------------------------------------------------------------------------- /day3/v1.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day3/v1.mem.pprof -------------------------------------------------------------------------------- /day3/v2.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day3/v2.cpu.pprof -------------------------------------------------------------------------------- /day3/v2.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day3/v2.mem.pprof -------------------------------------------------------------------------------- /day4/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v1.cpu.pprof -------------------------------------------------------------------------------- /day4/v1.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v1.mem.pprof -------------------------------------------------------------------------------- /day4/v2.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v2.cpu.pprof -------------------------------------------------------------------------------- /day4/v2.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v2.mem.pprof -------------------------------------------------------------------------------- /day4/v3.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v3.cpu.pprof -------------------------------------------------------------------------------- /day4/v3.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v3.mem.pprof -------------------------------------------------------------------------------- /day4/v4.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v4.cpu.pprof -------------------------------------------------------------------------------- /day4/v4.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v4.mem.pprof -------------------------------------------------------------------------------- /day4/v5.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5.cpu.pprof -------------------------------------------------------------------------------- /day4/v5.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5.mem.pprof -------------------------------------------------------------------------------- /day5/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day5/v1.cpu.pprof -------------------------------------------------------------------------------- /day5/v1.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day5/v1.mem.pprof -------------------------------------------------------------------------------- /day5/v2.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day5/v2.cpu.pprof -------------------------------------------------------------------------------- /day5/v2.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day5/v2.mem.pprof -------------------------------------------------------------------------------- /day5/v3.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day5/v3.cpu.pprof -------------------------------------------------------------------------------- /day5/v3.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day5/v3.mem.pprof -------------------------------------------------------------------------------- /day5/v4.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day5/v4.cpu.pprof -------------------------------------------------------------------------------- /day5/v4.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day5/v4.mem.pprof -------------------------------------------------------------------------------- /day5/v5.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day5/v5.cpu.pprof -------------------------------------------------------------------------------- /day5/v5.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day5/v5.mem.pprof -------------------------------------------------------------------------------- /day6/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day6/v1.cpu.pprof -------------------------------------------------------------------------------- /day6/v1.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day6/v1.mem.pprof -------------------------------------------------------------------------------- /day6/v2.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day6/v2.cpu.pprof -------------------------------------------------------------------------------- /day6/v2.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day6/v2.mem.pprof -------------------------------------------------------------------------------- /day6/v3.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day6/v3.cpu.pprof -------------------------------------------------------------------------------- /day6/v3.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day6/v3.mem.pprof -------------------------------------------------------------------------------- /day6/v4.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day6/v4.cpu.pprof -------------------------------------------------------------------------------- /day6/v4.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day6/v4.mem.pprof -------------------------------------------------------------------------------- /day6/v5.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day6/v5.cpu.pprof -------------------------------------------------------------------------------- /day6/v5.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day6/v5.mem.pprof -------------------------------------------------------------------------------- /day7/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day7/v1.cpu.pprof -------------------------------------------------------------------------------- /day7/v1.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day7/v1.mem.pprof -------------------------------------------------------------------------------- /day7/v2.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day7/v2.cpu.pprof -------------------------------------------------------------------------------- /day7/v2.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day7/v2.mem.pprof -------------------------------------------------------------------------------- /day19/v1.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day19/v1.cpu.pprof -------------------------------------------------------------------------------- /day19/v1.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day19/v1.mem.pprof -------------------------------------------------------------------------------- /day4/v3-2.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v3-2.cpu.pprof -------------------------------------------------------------------------------- /day4/v3-2.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v3-2.mem.pprof -------------------------------------------------------------------------------- /day6/v2-2.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day6/v2-2.cpu.pprof -------------------------------------------------------------------------------- /day6/v2-2.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day6/v2-2.mem.pprof -------------------------------------------------------------------------------- /day6/v2-80.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day6/v2-80.cpu.pprof -------------------------------------------------------------------------------- /day6/v2-80.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day6/v2-80.mem.pprof -------------------------------------------------------------------------------- /day4/v5-10workers.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-10workers.cpu.pprof -------------------------------------------------------------------------------- /day4/v5-10workers.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-10workers.mem.pprof -------------------------------------------------------------------------------- /day4/v5-2workers.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-2workers.cpu.pprof -------------------------------------------------------------------------------- /day4/v5-2workers.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-2workers.mem.pprof -------------------------------------------------------------------------------- /day4/v5-4workers.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-4workers.cpu.pprof -------------------------------------------------------------------------------- /day4/v5-4workers.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-4workers.mem.pprof -------------------------------------------------------------------------------- /day4/v5-1workers2proc.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-1workers2proc.cpu.pprof -------------------------------------------------------------------------------- /day4/v5-1workers2proc.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-1workers2proc.mem.pprof -------------------------------------------------------------------------------- /day4/v5-2workers1proc.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-2workers1proc.cpu.pprof -------------------------------------------------------------------------------- /day4/v5-2workers1proc.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-2workers1proc.mem.pprof -------------------------------------------------------------------------------- /day4/v5-5workers1proc.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-5workers1proc.cpu.pprof -------------------------------------------------------------------------------- /day4/v5-5workers1proc.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-5workers1proc.mem.pprof -------------------------------------------------------------------------------- /day4/v5-5workers2proc.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-5workers2proc.cpu.pprof -------------------------------------------------------------------------------- /day4/v5-5workers2proc.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-5workers2proc.mem.pprof -------------------------------------------------------------------------------- /day4/v5-5workers3proc.cpu.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-5workers3proc.cpu.pprof -------------------------------------------------------------------------------- /day4/v5-5workers3proc.mem.pprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwplotka/efficiency-coding-advent/HEAD/day4/v5-5workers3proc.mem.pprof -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | 17 | .idea/ -------------------------------------------------------------------------------- /day6/input.txt: -------------------------------------------------------------------------------- 1 | 2,1,2,1,5,1,5,1,2,2,1,1,5,1,4,4,4,3,1,2,2,3,4,1,1,5,1,1,4,2,5,5,5,1,1,4,5,4,1,1,4,2,1,4,1,2,2,5,1,1,5,1,1,3,4,4,1,2,3,1,5,5,4,1,4,1,2,1,5,1,1,1,3,4,1,1,5,1,5,1,1,5,1,1,4,3,2,4,1,4,1,5,3,3,1,5,1,3,1,1,4,1,4,5,2,3,1,1,1,1,3,1,2,1,5,1,1,5,1,1,1,1,4,1,4,3,1,5,1,1,5,4,4,2,1,4,5,1,1,3,3,1,1,4,2,5,5,2,4,1,4,5,4,5,3,1,4,1,5,2,4,5,3,1,3,2,4,5,4,4,1,5,1,5,1,2,2,1,4,1,1,4,2,2,2,4,1,1,5,3,1,1,5,4,4,1,5,1,3,1,3,2,2,1,1,4,1,4,1,2,2,1,1,3,5,1,2,1,3,1,4,5,1,3,4,1,1,1,1,4,3,3,4,5,1,1,1,1,1,2,4,5,3,4,2,1,1,1,3,3,1,4,1,1,4,2,1,5,1,1,2,3,4,2,5,1,1,1,5,1,1,4,1,2,4,1,1,2,4,3,4,2,3,1,1,2,1,5,4,2,3,5,1,2,3,1,2,2,1,4 -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/bwplotka/efficiency-advent-2021 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/efficientgo/tools/core v0.0.0-20210829154005-c7bad8450208 7 | github.com/go-gl/mathgl v1.0.0 8 | github.com/pkg/errors v0.9.1 9 | ) 10 | 11 | require ( 12 | github.com/davecgh/go-spew v1.1.1 // indirect 13 | github.com/pmezard/go-difflib v1.0.0 // indirect 14 | go.uber.org/goleak v1.1.10 // indirect 15 | golang.org/x/image v0.0.0-20210216034530-4410531fe030 // indirect 16 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect 17 | golang.org/x/tools v0.1.7 // indirect 18 | ) 19 | -------------------------------------------------------------------------------- /day2/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day2 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkDivePart2-12 12020 100391 ns/op 7074 B/op 1005 allocs/op 6 | BenchmarkDivePart2-12 10000 102185 ns/op 7073 B/op 1005 allocs/op 7 | BenchmarkDivePart2-12 10000 102113 ns/op 7072 B/op 1005 allocs/op 8 | BenchmarkDivePart2-12 10000 102658 ns/op 7072 B/op 1005 allocs/op 9 | BenchmarkDivePart2-12 10000 102717 ns/op 7072 B/op 1005 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day2 6.537s 12 | -------------------------------------------------------------------------------- /day2/v2.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day2 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkDivePart2-12 37299 32132 ns/op 4000 B/op 1000 allocs/op 6 | BenchmarkDivePart2-12 37044 31993 ns/op 4000 B/op 1000 allocs/op 7 | BenchmarkDivePart2-12 38050 33202 ns/op 4000 B/op 1000 allocs/op 8 | BenchmarkDivePart2-12 36888 38831 ns/op 4000 B/op 1000 allocs/op 9 | BenchmarkDivePart2-12 21780 48504 ns/op 4000 B/op 1000 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day2 8.171s 12 | -------------------------------------------------------------------------------- /day2/v3.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day2 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkDivePart2-12 140990 8192 ns/op 0 B/op 0 allocs/op 6 | BenchmarkDivePart2-12 149779 8089 ns/op 0 B/op 0 allocs/op 7 | BenchmarkDivePart2-12 149187 8095 ns/op 0 B/op 0 allocs/op 8 | BenchmarkDivePart2-12 133420 8560 ns/op 0 B/op 0 allocs/op 9 | BenchmarkDivePart2-12 145518 8141 ns/op 0 B/op 0 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day2 6.526s 12 | -------------------------------------------------------------------------------- /day2/v4.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day2 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkDivePart2-12 109737 10068 ns/op 0 B/op 0 allocs/op 6 | BenchmarkDivePart2-12 120290 9821 ns/op 0 B/op 0 allocs/op 7 | BenchmarkDivePart2-12 118672 10016 ns/op 0 B/op 0 allocs/op 8 | BenchmarkDivePart2-12 120644 10364 ns/op 0 B/op 0 allocs/op 9 | BenchmarkDivePart2-12 111513 10417 ns/op 0 B/op 0 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day2 6.625s 12 | -------------------------------------------------------------------------------- /day2/v5.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day2 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkDivePart2-12 144866 7886 ns/op 0 B/op 0 allocs/op 6 | BenchmarkDivePart2-12 150199 7829 ns/op 0 B/op 0 allocs/op 7 | BenchmarkDivePart2-12 150613 7932 ns/op 0 B/op 0 allocs/op 8 | BenchmarkDivePart2-12 149846 7709 ns/op 0 B/op 0 allocs/op 9 | BenchmarkDivePart2-12 150807 7962 ns/op 0 B/op 0 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day2 6.425s 12 | -------------------------------------------------------------------------------- /day4/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day4 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBingoPart2-12 7471 159623 ns/op 8041 B/op 21 allocs/op 6 | BenchmarkBingoPart2-12 7802 150803 ns/op 8039 B/op 21 allocs/op 7 | BenchmarkBingoPart2-12 7909 155531 ns/op 8039 B/op 21 allocs/op 8 | BenchmarkBingoPart2-12 7899 150641 ns/op 8038 B/op 21 allocs/op 9 | BenchmarkBingoPart2-12 7899 157192 ns/op 8039 B/op 21 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day4 6.245s 12 | -------------------------------------------------------------------------------- /day4/v2.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day4 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBingoPart2-12 6975 153308 ns/op 8039 B/op 21 allocs/op 6 | BenchmarkBingoPart2-12 7971 150156 ns/op 8038 B/op 21 allocs/op 7 | BenchmarkBingoPart2-12 8157 150277 ns/op 8036 B/op 21 allocs/op 8 | BenchmarkBingoPart2-12 8136 156221 ns/op 8038 B/op 21 allocs/op 9 | BenchmarkBingoPart2-12 7878 150751 ns/op 8039 B/op 21 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day4 6.147s 12 | -------------------------------------------------------------------------------- /day4/v3.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day4 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBingoPart2-12 37442 30926 ns/op 3832 B/op 9 allocs/op 6 | BenchmarkBingoPart2-12 38638 32698 ns/op 3832 B/op 9 allocs/op 7 | BenchmarkBingoPart2-12 37989 31142 ns/op 3832 B/op 9 allocs/op 8 | BenchmarkBingoPart2-12 38776 31236 ns/op 3832 B/op 9 allocs/op 9 | BenchmarkBingoPart2-12 39606 31233 ns/op 3832 B/op 9 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day4 7.754s 12 | -------------------------------------------------------------------------------- /day4/v3-2.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day4 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBingoPart2-12 36636 30531 ns/op 3832 B/op 9 allocs/op 6 | BenchmarkBingoPart2-12 39074 31471 ns/op 3832 B/op 9 allocs/op 7 | BenchmarkBingoPart2-12 39427 30203 ns/op 3832 B/op 9 allocs/op 8 | BenchmarkBingoPart2-12 33025 30425 ns/op 3832 B/op 9 allocs/op 9 | BenchmarkBingoPart2-12 39541 31368 ns/op 3832 B/op 9 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day4 7.551s 12 | -------------------------------------------------------------------------------- /day7/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day7 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkMinFuelPart2-12 438 2600777 ns/op 1 B/op 0 allocs/op 6 | BenchmarkMinFuelPart2-12 452 2912538 ns/op 0 B/op 0 allocs/op 7 | BenchmarkMinFuelPart2-12 412 2831370 ns/op 0 B/op 0 allocs/op 8 | BenchmarkMinFuelPart2-12 417 2979099 ns/op 0 B/op 0 allocs/op 9 | BenchmarkMinFuelPart2-12 409 2650772 ns/op 0 B/op 0 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day7 7.530s 12 | -------------------------------------------------------------------------------- /day7/v2.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day7 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkMinFuelPart2-12 59026 19516 ns/op 0 B/op 0 allocs/op 6 | BenchmarkMinFuelPart2-12 58605 19878 ns/op 0 B/op 0 allocs/op 7 | BenchmarkMinFuelPart2-12 62456 20164 ns/op 0 B/op 0 allocs/op 8 | BenchmarkMinFuelPart2-12 61219 19617 ns/op 0 B/op 0 allocs/op 9 | BenchmarkMinFuelPart2-12 63158 19602 ns/op 0 B/op 0 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day7 7.228s 12 | -------------------------------------------------------------------------------- /day6/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day6 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkSimLanternfish-12 192 8158963 ns/op 14632229 B/op 35 allocs/op 6 | BenchmarkSimLanternfish-12 205 9966644 ns/op 14632315 B/op 35 allocs/op 7 | BenchmarkSimLanternfish-12 183 12710254 ns/op 14632345 B/op 35 allocs/op 8 | BenchmarkSimLanternfish-12 100 11376176 ns/op 14632197 B/op 35 allocs/op 9 | BenchmarkSimLanternfish-12 100 11404320 ns/op 14632206 B/op 35 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day6 11.357s 12 | -------------------------------------------------------------------------------- /day6/v2.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day6 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkSimLanternfish-12 375940 3137 ns/op 0 B/op 0 allocs/op 6 | BenchmarkSimLanternfish-12 382128 3003 ns/op 0 B/op 0 allocs/op 7 | BenchmarkSimLanternfish-12 389814 3009 ns/op 0 B/op 0 allocs/op 8 | BenchmarkSimLanternfish-12 397851 3014 ns/op 0 B/op 0 allocs/op 9 | BenchmarkSimLanternfish-12 398107 3120 ns/op 0 B/op 0 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day6 6.221s 12 | -------------------------------------------------------------------------------- /day6/v3.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day6 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkSimLanternfish-12 873980 1345 ns/op 0 B/op 0 allocs/op 6 | BenchmarkSimLanternfish-12 877224 1345 ns/op 0 B/op 0 allocs/op 7 | BenchmarkSimLanternfish-12 868021 1533 ns/op 0 B/op 0 allocs/op 8 | BenchmarkSimLanternfish-12 846368 1343 ns/op 0 B/op 0 allocs/op 9 | BenchmarkSimLanternfish-12 885637 1342 ns/op 0 B/op 0 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day6 7.225s 12 | -------------------------------------------------------------------------------- /day6/v2-2.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day6 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkSimLanternfish-12 310702 3372 ns/op 0 B/op 0 allocs/op 6 | BenchmarkSimLanternfish-12 375151 3141 ns/op 0 B/op 0 allocs/op 7 | BenchmarkSimLanternfish-12 373714 3121 ns/op 0 B/op 0 allocs/op 8 | BenchmarkSimLanternfish-12 380260 3217 ns/op 0 B/op 0 allocs/op 9 | BenchmarkSimLanternfish-12 379346 3339 ns/op 0 B/op 0 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day6 6.225s 12 | -------------------------------------------------------------------------------- /day6/v2-80.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day6 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkSimLanternfish-12 381728 3107 ns/op 0 B/op 0 allocs/op 6 | BenchmarkSimLanternfish-12 367113 3172 ns/op 0 B/op 0 allocs/op 7 | BenchmarkSimLanternfish-12 396651 3116 ns/op 0 B/op 0 allocs/op 8 | BenchmarkSimLanternfish-12 391771 3012 ns/op 0 B/op 0 allocs/op 9 | BenchmarkSimLanternfish-12 398734 3029 ns/op 0 B/op 0 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day6 6.324s 12 | -------------------------------------------------------------------------------- /day3/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day3 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBinDiagnosePart2-12 17580 144643 ns/op 65505 B/op 22 allocs/op 6 | BenchmarkBinDiagnosePart2-12 10466 110533 ns/op 65504 B/op 22 allocs/op 7 | BenchmarkBinDiagnosePart2-12 9572 110835 ns/op 65504 B/op 22 allocs/op 8 | BenchmarkBinDiagnosePart2-12 10000 122742 ns/op 65504 B/op 22 allocs/op 9 | BenchmarkBinDiagnosePart2-12 13702 122920 ns/op 65506 B/op 22 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day3 10.668s 12 | -------------------------------------------------------------------------------- /day3/v2.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day3 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBinDiagnosePart2-12 91899 22916 ns/op 16384 B/op 2 allocs/op 6 | BenchmarkBinDiagnosePart2-12 62972 35260 ns/op 16384 B/op 2 allocs/op 7 | BenchmarkBinDiagnosePart2-12 76806 27613 ns/op 16384 B/op 2 allocs/op 8 | BenchmarkBinDiagnosePart2-12 42222 34163 ns/op 16384 B/op 2 allocs/op 9 | BenchmarkBinDiagnosePart2-12 72344 18389 ns/op 16384 B/op 2 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day3 15.068s 12 | -------------------------------------------------------------------------------- /day6/v4.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day6 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkSimLanternfish-12 2369788 511.6 ns/op 0 B/op 0 allocs/op 6 | BenchmarkSimLanternfish-12 2435820 495.2 ns/op 0 B/op 0 allocs/op 7 | BenchmarkSimLanternfish-12 2412206 490.3 ns/op 0 B/op 0 allocs/op 8 | BenchmarkSimLanternfish-12 2426490 505.6 ns/op 0 B/op 0 allocs/op 9 | BenchmarkSimLanternfish-12 2446710 491.1 ns/op 0 B/op 0 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day6 8.728s 12 | -------------------------------------------------------------------------------- /day6/v5.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day6 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkSimLanternfish-12 2760381 461.3 ns/op 0 B/op 0 allocs/op 6 | BenchmarkSimLanternfish-12 2572274 443.0 ns/op 0 B/op 0 allocs/op 7 | BenchmarkSimLanternfish-12 2869244 441.0 ns/op 0 B/op 0 allocs/op 8 | BenchmarkSimLanternfish-12 2911776 420.0 ns/op 0 B/op 0 allocs/op 9 | BenchmarkSimLanternfish-12 2942997 406.2 ns/op 0 B/op 0 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day6 8.435s 12 | -------------------------------------------------------------------------------- /day5/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day5 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkVentsOverlapPart2-12 186 7515385 ns/op 2829493 B/op 18114 allocs/op 6 | BenchmarkVentsOverlapPart2-12 170 6827051 ns/op 2829404 B/op 18113 allocs/op 7 | BenchmarkVentsOverlapPart2-12 196 7694769 ns/op 2829846 B/op 18115 allocs/op 8 | BenchmarkVentsOverlapPart2-12 159 7311847 ns/op 2829450 B/op 18114 allocs/op 9 | BenchmarkVentsOverlapPart2-12 141 9115424 ns/op 2829868 B/op 18116 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day5 10.266s 12 | -------------------------------------------------------------------------------- /day5/v2.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day5 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkVentsOverlapPart2-12 274 4683023 ns/op 1389558 B/op 2005 allocs/op 6 | BenchmarkVentsOverlapPart2-12 236 4611815 ns/op 1390317 B/op 2011 allocs/op 7 | BenchmarkVentsOverlapPart2-12 259 4883815 ns/op 1390158 B/op 2010 allocs/op 8 | BenchmarkVentsOverlapPart2-12 235 5070837 ns/op 1390363 B/op 2011 allocs/op 9 | BenchmarkVentsOverlapPart2-12 265 5169665 ns/op 1389728 B/op 2007 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day5 9.865s 12 | -------------------------------------------------------------------------------- /day5/v3.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day5 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkVentsOverlapPart2-12 370 3396441 ns/op 1055628 B/op 1501 allocs/op 6 | BenchmarkVentsOverlapPart2-12 376 3098529 ns/op 1055626 B/op 1501 allocs/op 7 | BenchmarkVentsOverlapPart2-12 363 3088262 ns/op 1055654 B/op 1501 allocs/op 8 | BenchmarkVentsOverlapPart2-12 408 3082711 ns/op 1055616 B/op 1501 allocs/op 9 | BenchmarkVentsOverlapPart2-12 393 3135813 ns/op 1055619 B/op 1501 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day5 7.747s 12 | -------------------------------------------------------------------------------- /day5/v4.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day5 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkVentsOverlapPart2-12 636 2857428 ns/op 1007640 B/op 1 allocs/op 6 | BenchmarkVentsOverlapPart2-12 531 2685009 ns/op 1007647 B/op 1 allocs/op 7 | BenchmarkVentsOverlapPart2-12 366 2879514 ns/op 1007617 B/op 1 allocs/op 8 | BenchmarkVentsOverlapPart2-12 638 2825945 ns/op 1007633 B/op 1 allocs/op 9 | BenchmarkVentsOverlapPart2-12 500 2718489 ns/op 1007616 B/op 1 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day5 8.758s 12 | -------------------------------------------------------------------------------- /day19/v1.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day19 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkManhattanDistPart2-12 4 322309645 ns/op 1067224 B/op 6644 allocs/op 6 | BenchmarkManhattanDistPart2-12 4 325133443 ns/op 1062434 B/op 6620 allocs/op 7 | BenchmarkManhattanDistPart2-12 4 322454443 ns/op 1063370 B/op 6634 allocs/op 8 | BenchmarkManhattanDistPart2-12 3 335517074 ns/op 1060912 B/op 6587 allocs/op 9 | BenchmarkManhattanDistPart2-12 3 333532506 ns/op 1065176 B/op 6626 allocs/op 10 | PASS 11 | ok github.com/bwplotka/efficiency-advent-2021/day19 10.550s 12 | -------------------------------------------------------------------------------- /day4/v4.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day4 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBingoPart2-12 10000 129232 ns/op 13325 B/op 205 allocs/op 6 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 6 7 | BenchmarkBingoPart2-12 10000 114401 ns/op 13324 B/op 205 allocs/op 8 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 6 9 | BenchmarkBingoPart2-12 10000 172525 ns/op 13323 B/op 205 allocs/op 10 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 6 11 | BenchmarkBingoPart2-12 15261 148271 ns/op 13322 B/op 205 allocs/op 12 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 6 13 | BenchmarkBingoPart2-12 6756 195579 ns/op 13320 B/op 205 allocs/op 14 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 6 15 | PASS 16 | ok github.com/bwplotka/efficiency-advent-2021/day4 9.621s 17 | -------------------------------------------------------------------------------- /day4/v5.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day4 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBingoPart2-12 59637 20458 ns/op 5192 B/op 19 allocs/op 6 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 6 7 | BenchmarkBingoPart2-12 59305 23165 ns/op 5192 B/op 19 allocs/op 8 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 6 9 | BenchmarkBingoPart2-12 61647 20371 ns/op 5192 B/op 19 allocs/op 10 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 6 11 | BenchmarkBingoPart2-12 44112 23018 ns/op 5192 B/op 19 allocs/op 12 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 6 13 | BenchmarkBingoPart2-12 60357 20934 ns/op 5192 B/op 19 allocs/op 14 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 6 15 | PASS 16 | ok github.com/bwplotka/efficiency-advent-2021/day4 7.417s 17 | -------------------------------------------------------------------------------- /day4/v5-2workers.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day4 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBingoPart2-12 66160 17526 ns/op 4712 B/op 9 allocs/op 6 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 7 | BenchmarkBingoPart2-12 68612 17240 ns/op 4712 B/op 9 allocs/op 8 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 9 | BenchmarkBingoPart2-12 68947 18527 ns/op 4712 B/op 9 allocs/op 10 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 11 | BenchmarkBingoPart2-12 69434 17413 ns/op 4712 B/op 9 allocs/op 12 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 13 | BenchmarkBingoPart2-12 68821 17327 ns/op 4712 B/op 9 allocs/op 14 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 15 | PASS 16 | ok github.com/bwplotka/efficiency-advent-2021/day4 7.114s 17 | -------------------------------------------------------------------------------- /day4/v5-4workers.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day4 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBingoPart2-12 65654 18128 ns/op 4904 B/op 13 allocs/op 6 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 4 7 | BenchmarkBingoPart2-12 66880 18887 ns/op 4904 B/op 13 allocs/op 8 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 4 9 | BenchmarkBingoPart2-12 66418 17900 ns/op 4904 B/op 13 allocs/op 10 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 4 11 | BenchmarkBingoPart2-12 66696 18510 ns/op 4904 B/op 13 allocs/op 12 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 4 13 | BenchmarkBingoPart2-12 68155 18513 ns/op 4904 B/op 13 allocs/op 14 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 4 15 | PASS 16 | ok github.com/bwplotka/efficiency-advent-2021/day4 7.216s 17 | -------------------------------------------------------------------------------- /day4/v5-10workers.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day4 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBingoPart2-12 57522 22436 ns/op 5480 B/op 25 allocs/op 6 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 10 7 | BenchmarkBingoPart2-12 45198 23369 ns/op 5480 B/op 25 allocs/op 8 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 10 9 | BenchmarkBingoPart2-12 52566 24449 ns/op 5480 B/op 25 allocs/op 10 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 10 11 | BenchmarkBingoPart2-12 52855 30209 ns/op 5480 B/op 25 allocs/op 12 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 10 13 | BenchmarkBingoPart2-12 51644 24121 ns/op 5480 B/op 25 allocs/op 14 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 10 15 | PASS 16 | ok github.com/bwplotka/efficiency-advent-2021/day4 7.837s 17 | -------------------------------------------------------------------------------- /day4/v5-1workers2proc.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day4 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBingoPart2-12 45890 25340 ns/op 4616 B/op 7 allocs/op 6 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 7 | BenchmarkBingoPart2-12 47569 25755 ns/op 4616 B/op 7 allocs/op 8 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 9 | BenchmarkBingoPart2-12 48139 25503 ns/op 4616 B/op 7 allocs/op 10 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 11 | BenchmarkBingoPart2-12 48480 25732 ns/op 4616 B/op 7 allocs/op 12 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 13 | BenchmarkBingoPart2-12 48052 25088 ns/op 4616 B/op 7 allocs/op 14 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 15 | PASS 16 | ok github.com/bwplotka/efficiency-advent-2021/day4 7.515s 17 | -------------------------------------------------------------------------------- /day4/v5-2workers1proc.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day4 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBingoPart2-12 51795 23404 ns/op 4712 B/op 9 allocs/op 6 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 1 7 | BenchmarkBingoPart2-12 52360 22045 ns/op 4712 B/op 9 allocs/op 8 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 1 9 | BenchmarkBingoPart2-12 50030 21802 ns/op 4712 B/op 9 allocs/op 10 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 1 11 | BenchmarkBingoPart2-12 54864 22101 ns/op 4712 B/op 9 allocs/op 12 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 1 13 | BenchmarkBingoPart2-12 54663 22848 ns/op 4712 B/op 9 allocs/op 14 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 1 15 | PASS 16 | ok github.com/bwplotka/efficiency-advent-2021/day4 7.213s 17 | -------------------------------------------------------------------------------- /day4/v5-5workers1proc.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day4 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBingoPart2-12 49490 24035 ns/op 5000 B/op 15 allocs/op 6 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 1 7 | BenchmarkBingoPart2-12 46923 22747 ns/op 5000 B/op 15 allocs/op 8 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 1 9 | BenchmarkBingoPart2-12 51285 23299 ns/op 5000 B/op 15 allocs/op 10 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 1 11 | BenchmarkBingoPart2-12 52538 22706 ns/op 5000 B/op 15 allocs/op 12 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 1 13 | BenchmarkBingoPart2-12 51810 23254 ns/op 5000 B/op 15 allocs/op 14 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 1 15 | PASS 16 | ok github.com/bwplotka/efficiency-advent-2021/day4 8.216s 17 | -------------------------------------------------------------------------------- /day4/v5-5workers2proc.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day4 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBingoPart2-12 62655 18933 ns/op 5000 B/op 15 allocs/op 6 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 7 | BenchmarkBingoPart2-12 64941 18718 ns/op 5000 B/op 15 allocs/op 8 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 9 | BenchmarkBingoPart2-12 65372 19089 ns/op 5000 B/op 15 allocs/op 10 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 11 | BenchmarkBingoPart2-12 65247 18607 ns/op 5000 B/op 15 allocs/op 12 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 13 | BenchmarkBingoPart2-12 65685 18910 ns/op 5000 B/op 15 allocs/op 14 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 2 15 | PASS 16 | ok github.com/bwplotka/efficiency-advent-2021/day4 7.213s 17 | -------------------------------------------------------------------------------- /day4/v5-5workers3proc.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day4 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkBingoPart2-12 68278 17795 ns/op 5000 B/op 15 allocs/op 6 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 3 7 | BenchmarkBingoPart2-12 64564 18525 ns/op 5000 B/op 15 allocs/op 8 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 3 9 | BenchmarkBingoPart2-12 68968 17658 ns/op 5000 B/op 15 allocs/op 10 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 3 11 | BenchmarkBingoPart2-12 71062 18038 ns/op 5000 B/op 15 allocs/op 12 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 3 13 | BenchmarkBingoPart2-12 71199 18016 ns/op 5000 B/op 15 allocs/op 14 | testing: BenchmarkBingoPart2-12 left GOMAXPROCS set to 3 15 | PASS 16 | ok github.com/bwplotka/efficiency-advent-2021/day4 7.217s 17 | -------------------------------------------------------------------------------- /day5/v5.txt: -------------------------------------------------------------------------------- 1 | goos: linux 2 | goarch: amd64 3 | pkg: github.com/bwplotka/efficiency-advent-2021/day5 4 | cpu: Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz 5 | BenchmarkVentsOverlapPart2-12 1278 878842 ns/op 1082065 B/op 16 allocs/op 6 | testing: BenchmarkVentsOverlapPart2-12 left GOMAXPROCS set to 4 7 | BenchmarkVentsOverlapPart2-12 1383 889050 ns/op 1082009 B/op 16 allocs/op 8 | testing: BenchmarkVentsOverlapPart2-12 left GOMAXPROCS set to 4 9 | BenchmarkVentsOverlapPart2-12 1196 978087 ns/op 1082029 B/op 16 allocs/op 10 | testing: BenchmarkVentsOverlapPart2-12 left GOMAXPROCS set to 4 11 | BenchmarkVentsOverlapPart2-12 1336 917981 ns/op 1082013 B/op 16 allocs/op 12 | testing: BenchmarkVentsOverlapPart2-12 left GOMAXPROCS set to 4 13 | BenchmarkVentsOverlapPart2-12 1416 924982 ns/op 1082006 B/op 16 allocs/op 14 | testing: BenchmarkVentsOverlapPart2-12 left GOMAXPROCS set to 4 15 | PASS 16 | ok github.com/bwplotka/efficiency-advent-2021/day5 6.722s 17 | -------------------------------------------------------------------------------- /day7/main_test.go: -------------------------------------------------------------------------------- 1 | package day7 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/bwplotka/efficiency-advent-2021/day2" 8 | "github.com/efficientgo/tools/core/pkg/testutil" 9 | ) 10 | 11 | func TestMinFuelPart1(t *testing.T) { 12 | for _, tcase := range []struct { 13 | input string 14 | expected int64 15 | }{ 16 | { 17 | input: `16,1,2,0,4,2,7,1,2,14`, 18 | expected: 37, 19 | }, 20 | { 21 | input: day2.ReadTestInput(t), // 300 initial 22 | expected: 340987, 23 | }, 24 | } { 25 | t.Run("", func(t *testing.T) { 26 | input := strings.TrimSpace(tcase.input) + "\n" 27 | 28 | t.Run("MinFuelPart1", func(t *testing.T) { 29 | ans, err := MinFuelPart1(input) 30 | testutil.Ok(t, err) 31 | testutil.Equals(t, tcase.expected, int64(ans)) 32 | }) 33 | }) 34 | } 35 | } 36 | 37 | func TestMinFuelPart2(t *testing.T) { 38 | for _, tcase := range []struct { 39 | input string 40 | expected int64 41 | }{ 42 | { 43 | input: `16,1,2,0,4,2,7,1,2,14`, 44 | expected: 168, 45 | }, 46 | { 47 | input: day2.ReadTestInput(t), // 300 initial 48 | expected: 96987874, 49 | }, 50 | } { 51 | t.Run("", func(t *testing.T) { 52 | input := strings.TrimSpace(tcase.input) + "\n" 53 | 54 | t.Run("MinFuelPart2", func(t *testing.T) { 55 | ans, err := MinFuelPart2(input) 56 | testutil.Ok(t, err) 57 | testutil.Equals(t, tcase.expected, int64(ans)) 58 | }) 59 | t.Run("MinFuelPart2_V2", func(t *testing.T) { 60 | ans, err := MinFuelPart2_V2(input) 61 | testutil.Ok(t, err) 62 | testutil.Equals(t, tcase.expected, int64(ans)) 63 | }) 64 | }) 65 | } 66 | } 67 | 68 | var Answer int 69 | 70 | // go test -count 5 -run '^$' -bench . -memprofile=v1.mem.pprof -cpuprofile=v1.cpu.pprof > v1.txt 71 | func BenchmarkMinFuelPart2(b *testing.B) { 72 | b.ReportAllocs() 73 | input := strings.TrimSpace(day2.ReadTestInput(b)) + "\n" 74 | 75 | b.ResetTimer() 76 | for i := 0; i < b.N; i++ { 77 | Answer, _ = MinFuelPart2_V2(input) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /day3/main_test.go: -------------------------------------------------------------------------------- 1 | package day3 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/bwplotka/efficiency-advent-2021/day2" 8 | "github.com/efficientgo/tools/core/pkg/testutil" 9 | ) 10 | 11 | func TestBinDiagnosePart1(t *testing.T) { 12 | for _, tcase := range []struct { 13 | input string 14 | expected int 15 | }{ 16 | { 17 | input: `00100 18 | 11110 19 | 10110 20 | 10111 21 | 10101 22 | 01111 23 | 00111 24 | 11100 25 | 10000 26 | 11001 27 | 00010 28 | 01010`, 29 | expected: 198, 30 | }, 31 | { 32 | input: day2.ReadTestInput(t), 33 | expected: 3429254, 34 | }, 35 | } { 36 | t.Run("", func(t *testing.T) { 37 | input := strings.TrimSpace(tcase.input) + "\n" 38 | 39 | t.Run("BinDiagnosePart1", func(t *testing.T) { 40 | ans, err := BinDiagnosePart1(input) 41 | testutil.Ok(t, err) 42 | testutil.Equals(t, tcase.expected, ans) 43 | }) 44 | }) 45 | } 46 | } 47 | 48 | func TestDivePart2(t *testing.T) { 49 | for _, tcase := range []struct { 50 | input string 51 | expected int 52 | }{ 53 | { 54 | input: `00100 55 | 11110 56 | 10110 57 | 10111 58 | 10101 59 | 01111 60 | 00111 61 | 11100 62 | 10000 63 | 11001 64 | 00010 65 | 01010`, 66 | expected: 230, 67 | }, 68 | { 69 | input: day2.ReadTestInput(t), 70 | expected: 5410338, 71 | }, 72 | } { 73 | t.Run("", func(t *testing.T) { 74 | input := strings.TrimSpace(tcase.input) + "\n" 75 | 76 | t.Run("BinDiagnosePart2", func(t *testing.T) { 77 | ans, err := BinDiagnosePart2(input) 78 | testutil.Ok(t, err) 79 | testutil.Equals(t, tcase.expected, ans) 80 | }) 81 | t.Run("BinDiagnosePart2_V2", func(t *testing.T) { 82 | ans, err := BinDiagnosePart2_V2(input) 83 | testutil.Ok(t, err) 84 | testutil.Equals(t, tcase.expected, ans) 85 | }) 86 | }) 87 | } 88 | } 89 | 90 | var Answer int 91 | 92 | // go test -count 5 -run '^$' -bench . -memprofile=v1.mem.pprof -cpuprofile=v1.cpu.pprof > v1.txt 93 | func BenchmarkBinDiagnosePart2(b *testing.B) { 94 | b.ReportAllocs() 95 | input := strings.TrimSpace(day2.ReadTestInput(b)) + "\n" 96 | 97 | b.ResetTimer() 98 | for i := 0; i < b.N; i++ { 99 | Answer, _ = BinDiagnosePart2(input) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # efficiency-advent-2021 2 | 3 | Repo for [Advent of Code 2021](https://adventofcode.com/2021) in Go with efficient solutions. Note that I focus on "maintainable" efficiency. Imagine those algorithms are needed in critical path, but normal humans have to still be able to maintain it! (: 4 | 5 | You will read more about tricks used here in [Efficient Go Book](https://www.oreilly.com/library/view/efficient-go/9781098105709/), but I left comments on various solutions through the challenges, enjoy! (: 6 | 7 | Inspired by [Advent of Go Profiling 2021](https://felixge.de/2021/12/01/advent-of-go-profiling-2021-day-1-1/.) 8 | 9 | Follow others in their Advent of Code journey too! 10 | 11 | * [@felixge](https://felixge.de/2021/12/01/advent-of-go-profiling-2021-day-1-1/) 12 | * [@kabanek](https://twitter.com/kabanek/status/1466284532269821959) 13 | 14 | ## How to Use this Repo 15 | 16 | Each day has two parts. Both are within the same `main.go` file within corresponding `dayXY` directory. You can find correctness tests and benchmarks within `main_test.go` 17 | 18 | Benchmark typically looks as follows: 19 | 20 | ```go 21 | var Answer int 22 | 23 | func BenchmarkFUNC_NAME(b *testing.B) { 24 | b.ReportAllocs() 25 | input := strings.TrimSpace(day2.ReadTestInput(b)) + "\n" 26 | 27 | b.ResetTimer() 28 | for i := 0; i < b.N; i++ { 29 | Answer, _ = FUNC_NAME(input) 30 | } 31 | } 32 | ``` 33 | 34 | Notice the `Answer` var on global scope. This makes sure Go compiler will not optimize our function away. 35 | 36 | You can run 5 tests, if you run command: 37 | 38 | You can run this test by going into directory with this file and running: 39 | 40 | `export var=v1 && go test -count 5 -run '^$' -bench . -memprofile=${var}.mem.pprof -cpuprofile=${var}.cpu.pprof > ${var}.txt` 41 | 42 | This will give pprof profiles you can inspect by running: 43 | 44 | `go tool pprof -edgefraction=0 -functions -http=:8081 ${var}.cpu.pprof` 45 | 46 | or for memory: 47 | 48 | `go tool pprof -edgefraction=0 -functions -http=:8081 ${var}.mem.pprof` 49 | 50 | You can also find output of benchmark using `benchstat` you can install using `go install golang.org/x/perf/cmd/benchstat`. This tool will get statistically correct value for multiple runs: 51 | 52 | `benchstat ${var}.txt` 53 | 54 | You can also compare different results across each other e.g v1 and v5: 55 | 56 | `benchstat v1.txt v5.txt` 57 | 58 | That's it! Enjoy (: 59 | -------------------------------------------------------------------------------- /day2/main_test.go: -------------------------------------------------------------------------------- 1 | package day2 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/efficientgo/tools/core/pkg/testutil" 8 | ) 9 | 10 | func TestDivePart1(t *testing.T) { 11 | for _, tcase := range []struct { 12 | input string 13 | expected int 14 | }{ 15 | { 16 | input: `forward 5 17 | down 5 18 | forward 8 19 | up 3 20 | down 8 21 | forward 2`, 22 | expected: 150, 23 | }, 24 | { 25 | input: ReadTestInput(t), 26 | expected: 1868935, 27 | }, 28 | } { 29 | t.Run("", func(t *testing.T) { 30 | input := strings.TrimSpace(tcase.input) + "\n" 31 | 32 | t.Run("DivePart1", func(t *testing.T) { 33 | ans, err := DivePart1(input) 34 | testutil.Ok(t, err) 35 | testutil.Equals(t, tcase.expected, ans) 36 | }) 37 | }) 38 | } 39 | } 40 | 41 | func TestDivePart2(t *testing.T) { 42 | for _, tcase := range []struct { 43 | input string 44 | expected int 45 | }{ 46 | { 47 | input: `forward 5 48 | down 5 49 | forward 8 50 | up 3 51 | down 8 52 | forward 2`, 53 | expected: 900, 54 | }, 55 | { 56 | input: ReadTestInput(t), 57 | expected: 1965970888, 58 | }, 59 | } { 60 | t.Run("", func(t *testing.T) { 61 | input := strings.TrimSpace(tcase.input) + "\n" 62 | 63 | t.Run("DivePart2", func(t *testing.T) { 64 | ans, err := DivePart2(input) 65 | testutil.Ok(t, err) 66 | testutil.Equals(t, tcase.expected, ans) 67 | }) 68 | t.Run("DivePart2_V2", func(t *testing.T) { 69 | ans, err := DivePart2_V2(input) 70 | testutil.Ok(t, err) 71 | testutil.Equals(t, tcase.expected, ans) 72 | }) 73 | t.Run("DivePart2_V3", func(t *testing.T) { 74 | ans, err := DivePart2_V3(input) 75 | testutil.Ok(t, err) 76 | testutil.Equals(t, tcase.expected, ans) 77 | }) 78 | t.Run("DivePart2_V4", func(t *testing.T) { 79 | ans, err := DivePart2_V4(input) 80 | testutil.Ok(t, err) 81 | testutil.Equals(t, tcase.expected, ans) 82 | }) 83 | t.Run("DivePart2_V5", func(t *testing.T) { 84 | ans, err := DivePart2_V5(input) 85 | testutil.Ok(t, err) 86 | testutil.Equals(t, tcase.expected, ans) 87 | }) 88 | }) 89 | } 90 | } 91 | 92 | var Answer int 93 | 94 | // go test -count 5 -run '^$' -bench . -memprofile=v1.mem.pprof -cpuprofile=v1.cpu.pprof > v1.txt 95 | func BenchmarkDivePart2(b *testing.B) { 96 | b.ReportAllocs() 97 | input := strings.TrimSpace(ReadTestInput(b)) + "\n" 98 | 99 | b.ResetTimer() 100 | for i := 0; i < b.N; i++ { 101 | Answer, _ = DivePart2_V5(input) 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /day6/main_test.go: -------------------------------------------------------------------------------- 1 | package day6 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/bwplotka/efficiency-advent-2021/day2" 8 | "github.com/efficientgo/tools/core/pkg/testutil" 9 | ) 10 | 11 | func TestSimLanternfish(t *testing.T) { 12 | for _, tcase := range []struct { 13 | input string 14 | days int 15 | expected int64 16 | }{ 17 | { 18 | input: `3,4,3,1,2`, 19 | days: 80, 20 | expected: 5934, 21 | }, 22 | { 23 | input: day2.ReadTestInput(t), // 300 initial 24 | days: 80, 25 | expected: 362639, 26 | }, 27 | { 28 | input: `3,4,3,1,2`, 29 | days: 256, 30 | expected: 26984457539, 31 | }, 32 | { 33 | input: day2.ReadTestInput(t), // 300 initial 34 | days: 256, 35 | expected: 1639854996917, 36 | }, 37 | } { 38 | t.Run("", func(t *testing.T) { 39 | input := strings.TrimSpace(tcase.input) + "\n" 40 | 41 | t.Run("SimLanternfish", func(t *testing.T) { 42 | if tcase.days > 80 { 43 | t.Skip("NOPE, too slow") 44 | } 45 | 46 | ans, err := SimLanternfish(input, tcase.days) 47 | testutil.Ok(t, err) 48 | testutil.Equals(t, tcase.expected, int64(ans)) 49 | }) 50 | t.Run("SimLanternfish_V2", func(t *testing.T) { 51 | ans, err := SimLanternfish_V2(input, tcase.days) 52 | testutil.Ok(t, err) 53 | testutil.Equals(t, tcase.expected, ans) 54 | }) 55 | t.Run("SimLanternfish_V3", func(t *testing.T) { 56 | ans, err := SimLanternfish_V3(input, tcase.days) 57 | testutil.Ok(t, err) 58 | testutil.Equals(t, tcase.expected, ans) 59 | }) 60 | t.Run("SimLanternfish_V4", func(t *testing.T) { 61 | ans, err := SimLanternfish_V4(input, tcase.days) 62 | testutil.Ok(t, err) 63 | testutil.Equals(t, tcase.expected, ans) 64 | }) 65 | t.Run("SimLanternfish_V5", func(t *testing.T) { 66 | ans, err := SimLanternfish_V4(input, tcase.days) 67 | testutil.Ok(t, err) 68 | testutil.Equals(t, tcase.expected, ans) 69 | }) 70 | }) 71 | } 72 | } 73 | 74 | var Answer int64 75 | 76 | // go test -count 5 -run '^$' -bench . -memprofile=v1.mem.pprof -cpuprofile=v1.cpu.pprof > v1.txt 77 | func BenchmarkSimLanternfish(b *testing.B) { 78 | b.ReportAllocs() 79 | input := strings.TrimSpace(day2.ReadTestInput(b)) + "\n" 80 | 81 | b.ResetTimer() 82 | for i := 0; i < b.N; i++ { 83 | Answer, _ = SimLanternfish_V5(input, 256) 84 | } 85 | } 86 | 87 | //// go test -count 5 -run '^$' -bench . -memprofile=v1.mem.pprof -cpuprofile=v1.cpu.pprof > v1.txt 88 | //func BenchmarkParseInt(b *testing.B) { 89 | // b.ReportAllocs() 90 | // 91 | // b.Run("std", func(b *testing.B) { 92 | // b.ResetTimer() 93 | // for i := 0; i < b.N; i++ { 94 | // Answer, _ = strconv.ParseInt("1234", 10, 64) 95 | // } 96 | // }) 97 | // b.Run("custom", func(b *testing.B) { 98 | // b.ResetTimer() 99 | // for i := 0; i < b.N; i++ { 100 | // Answer, _ = ParseInt("1234") 101 | // } 102 | // }) 103 | //} 104 | -------------------------------------------------------------------------------- /day7/main.go: -------------------------------------------------------------------------------- 1 | package day7 2 | 3 | import ( 4 | "math" 5 | "sort" 6 | "strconv" 7 | ) 8 | 9 | func MinFuelPart1(input string) (_ int, err error) { 10 | positions := make([]int, 0, 1000) 11 | for i := 0; i < len(input); { 12 | j := i 13 | 14 | for input[i] >= '0' && input[i] <= '9' { 15 | i++ 16 | } 17 | pos, err := strconv.ParseInt(input[j:i], 10, 64) 18 | if err != nil { 19 | return 0, err 20 | } 21 | i++ 22 | positions = append(positions, int(pos)) 23 | 24 | } 25 | sort.Ints(positions) 26 | 27 | median := positions[len(positions)/2] 28 | 29 | var fuelUsed int 30 | for _, p := range positions { 31 | if median > p { 32 | fuelUsed += median - p 33 | continue 34 | } 35 | 36 | fuelUsed += p - median 37 | } 38 | return fuelUsed, nil 39 | } 40 | 41 | func MinFuelPart2(input string) (_ int, err error) { 42 | positions := make([]int, 0, 1000) 43 | 44 | max := math.MinInt 45 | min := math.MaxInt 46 | for i := 0; i < len(input); { 47 | j := i 48 | 49 | for input[i] >= '0' && input[i] <= '9' { 50 | i++ 51 | } 52 | pos64, err := strconv.ParseInt(input[j:i], 10, 64) 53 | if err != nil { 54 | return 0, err 55 | } 56 | i++ 57 | pos := int(pos64) 58 | positions = append(positions, pos) 59 | 60 | if pos > max { 61 | max = pos 62 | } 63 | if pos < min { 64 | min = pos 65 | } 66 | } 67 | 68 | lowestFuel := math.MaxInt 69 | for i := min; i <= max; i++ { 70 | bestPos := i 71 | 72 | var fuelUsed int 73 | for _, p := range positions { 74 | distance := p - bestPos 75 | if bestPos > p { 76 | distance = bestPos - p 77 | } 78 | // Arithmetic progression: 79 | // Sn = ((a1 + an) / 2) * n 80 | fuelUsed += int(float64(1+distance) / 2.0 * float64(distance)) 81 | } 82 | 83 | if fuelUsed < lowestFuel { 84 | lowestFuel = fuelUsed 85 | } 86 | } 87 | 88 | return lowestFuel, nil 89 | } 90 | 91 | func MinFuelPart2_V2(input string) (_ int, err error) { 92 | positions := make([]int, 0, 1000) 93 | 94 | sum := 0 95 | for i := 0; i < len(input); { 96 | j := i 97 | 98 | for input[i] >= '0' && input[i] <= '9' { 99 | i++ 100 | } 101 | pos, err := strconv.ParseInt(input[j:i], 10, 64) 102 | if err != nil { 103 | return 0, err 104 | } 105 | i++ 106 | positions = append(positions, int(pos)) 107 | sum += int(pos) 108 | 109 | } 110 | mean := int(math.Ceil(float64(sum) / float64(len(positions)))) 111 | 112 | lowestFuel := math.MaxInt 113 | // Somewhere between those two should be lowest fuel number. 114 | for i := mean - 1; i <= mean; i++ { 115 | bestPos := i 116 | 117 | var fuelUsed int 118 | for _, p := range positions { 119 | distance := p - bestPos 120 | if bestPos > p { 121 | distance = bestPos - p 122 | } 123 | // Arithmetic progression: 124 | // Sn = ((a1 + an) / 2) * n 125 | fuelUsed += int(float64(1+distance) / 2.0 * float64(distance)) 126 | } 127 | 128 | if fuelUsed < lowestFuel { 129 | lowestFuel = fuelUsed 130 | } 131 | } 132 | 133 | return lowestFuel, nil 134 | } 135 | -------------------------------------------------------------------------------- /day4/main_test.go: -------------------------------------------------------------------------------- 1 | package day4 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/bwplotka/efficiency-advent-2021/day2" 8 | "github.com/efficientgo/tools/core/pkg/testutil" 9 | ) 10 | 11 | func TestBingoPart1(t *testing.T) { 12 | for _, tcase := range []struct { 13 | input string 14 | expected int 15 | }{ 16 | { 17 | input: `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 18 | 19 | 22 13 17 11 0 20 | 8 2 23 4 24 21 | 21 9 14 16 7 22 | 6 10 3 18 5 23 | 1 12 20 15 19 24 | 25 | 3 15 0 2 22 26 | 9 18 13 17 5 27 | 19 8 7 25 23 28 | 20 11 10 24 4 29 | 14 21 16 12 6 30 | 31 | 14 21 17 24 4 32 | 10 16 15 9 19 33 | 18 8 23 26 20 34 | 22 11 13 6 5 35 | 2 0 12 3 7`, 36 | expected: 4512, 37 | }, 38 | { 39 | input: day2.ReadTestInput(t), 40 | expected: 4662, 41 | }, 42 | } { 43 | t.Run("", func(t *testing.T) { 44 | input := tcase.input + "\n" 45 | 46 | t.Run("BingoPart1", func(t *testing.T) { 47 | ans, err := BingoPart1(input) 48 | testutil.Ok(t, err) 49 | testutil.Equals(t, tcase.expected, ans) 50 | }) 51 | }) 52 | } 53 | } 54 | 55 | func TestBignoPart2(t *testing.T) { 56 | for _, tcase := range []struct { 57 | input string 58 | expected int 59 | }{ 60 | { 61 | input: `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 62 | 63 | 22 13 17 11 0 64 | 8 2 23 4 24 65 | 21 9 14 16 7 66 | 6 10 3 18 5 67 | 1 12 20 15 19 68 | 69 | 3 15 0 2 22 70 | 9 18 13 17 5 71 | 19 8 7 25 23 72 | 20 11 10 24 4 73 | 14 21 16 12 6 74 | 75 | 14 21 17 24 4 76 | 10 16 15 9 19 77 | 18 8 23 26 20 78 | 22 11 13 6 5 79 | 2 0 12 3 7`, 80 | expected: 1924, 81 | }, 82 | { 83 | input: day2.ReadTestInput(t), 84 | expected: 12080, 85 | }, 86 | } { 87 | t.Run("", func(t *testing.T) { 88 | input := strings.TrimSpace(tcase.input) + "\n" 89 | 90 | t.Run("BingoPart2", func(t *testing.T) { 91 | ans, err := BingoPart2(input) 92 | testutil.Ok(t, err) 93 | testutil.Equals(t, tcase.expected, ans) 94 | }) 95 | t.Run("BingoPart2_V2", func(t *testing.T) { 96 | ans, err := BingoPart2_V2(input) 97 | testutil.Ok(t, err) 98 | testutil.Equals(t, tcase.expected, ans) 99 | }) 100 | t.Run("BingoPart2_V3", func(t *testing.T) { 101 | ans, err := BingoPart2_V3(input) 102 | testutil.Ok(t, err) 103 | testutil.Equals(t, tcase.expected, ans) 104 | }) 105 | t.Run("BingoPart2_V4", func(t *testing.T) { 106 | ans, err := BingoPart2_V4(input) 107 | testutil.Ok(t, err) 108 | testutil.Equals(t, tcase.expected, ans) 109 | }) 110 | t.Run("BingoPart2_V5", func(t *testing.T) { 111 | ans, err := BingoPart2_V5(input) 112 | testutil.Ok(t, err) 113 | testutil.Equals(t, tcase.expected, ans) 114 | }) 115 | }) 116 | } 117 | } 118 | 119 | var Answer int 120 | 121 | // go test -count 5 -run '^$' -bench . -memprofile=v1.mem.pprof -cpuprofile=v1.cpu.pprof > v1.txt 122 | func BenchmarkBingoPart2(b *testing.B) { 123 | b.ReportAllocs() 124 | input := strings.TrimSpace(day2.ReadTestInput(b)) + "\n" 125 | 126 | b.ResetTimer() 127 | for i := 0; i < b.N; i++ { 128 | Answer, _ = BingoPart2_V5(input) 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /day7/input.txt: -------------------------------------------------------------------------------- 1 | 1101,1,29,67,1102,0,1,65,1008,65,35,66,1005,66,28,1,67,65,20,4,0,1001,65,1,65,1106,0,8,99,35,67,101,99,105,32,110,39,101,115,116,32,112,97,115,32,117,110,101,32,105,110,116,99,111,100,101,32,112,114,111,103,114,97,109,10,591,116,168,1277,832,147,32,237,1060,589,149,100,137,603,662,290,361,139,1145,163,241,524,700,85,94,91,267,615,934,378,134,63,503,1022,87,44,711,26,567,49,141,80,53,1434,153,904,243,119,1064,9,202,18,1410,362,61,220,37,699,557,109,396,1065,1,928,614,351,169,498,282,156,614,879,199,259,1323,283,1128,307,374,60,218,1658,103,369,967,816,1037,694,160,1335,943,222,151,451,289,289,1079,604,165,111,130,228,45,368,153,122,356,923,691,183,386,1296,1868,367,1071,10,11,554,134,354,350,221,598,220,1082,361,35,982,18,4,11,13,262,281,57,325,204,1054,583,1166,474,141,9,788,157,85,345,903,2,365,863,661,140,131,1285,381,348,1443,926,172,374,1284,1285,915,380,433,854,11,352,152,1049,209,982,108,893,46,650,100,1653,834,1716,693,24,138,555,112,184,8,448,239,1226,45,788,109,178,517,173,152,364,190,344,951,97,644,716,746,882,58,74,149,716,1316,312,53,323,606,648,906,62,4,275,563,1092,192,527,6,58,376,350,594,50,179,483,693,321,1428,946,41,581,1794,1801,270,1344,902,1347,1064,19,168,687,1631,394,27,1327,98,212,285,436,602,936,760,175,984,1062,842,1133,572,153,792,677,1223,1949,296,221,1421,159,441,316,808,797,278,613,216,147,353,379,23,566,1149,76,232,431,1818,43,81,538,129,80,40,27,1178,348,60,512,343,378,321,1162,932,14,1293,72,846,351,632,1561,247,161,519,97,1361,350,683,118,142,16,34,1577,436,327,118,1102,195,154,579,1147,164,272,773,1017,556,549,589,32,52,118,417,394,133,29,512,1582,126,1106,156,175,484,875,467,544,300,462,22,437,255,507,355,405,1096,36,375,261,284,282,13,457,434,509,12,684,80,614,2,222,657,554,520,710,825,242,29,144,570,1116,182,861,209,159,247,191,423,733,386,385,774,810,22,131,76,105,235,1522,91,2,422,1133,81,11,151,341,317,1332,873,1218,374,0,49,19,73,268,332,60,558,244,595,210,535,7,409,985,970,223,286,84,486,246,675,1112,494,219,605,298,642,139,81,152,899,1181,157,1055,290,199,28,604,9,52,125,723,218,211,519,591,121,264,157,225,1431,172,26,424,212,1173,377,228,597,63,380,0,596,489,38,28,876,108,1669,169,295,318,251,847,1023,181,668,721,205,1376,1890,85,488,636,1022,21,1482,703,599,1136,427,513,186,1320,491,1502,528,4,247,393,152,363,243,1292,508,619,818,151,30,298,89,466,25,393,641,841,200,815,947,260,332,422,958,1186,382,814,1045,830,230,221,673,499,1402,867,635,57,814,1149,1027,830,331,1346,299,0,92,543,160,339,809,59,1128,259,271,1593,475,71,574,95,220,158,288,443,1052,156,450,1218,177,1351,204,1229,765,596,565,62,313,7,313,53,575,10,448,5,705,360,1371,1372,315,256,1323,136,62,807,238,343,173,904,67,680,162,509,231,524,196,218,681,715,552,658,183,1670,379,203,37,8,409,1403,371,69,361,511,272,498,46,489,1346,857,69,233,117,318,1199,977,871,308,435,42,797,550,406,91,171,133,1148,104,324,1489,942,530,468,196,293,534,613,73,29,497,814,1199,466,312,138,70,33,178,29,1549,98,442,23,1142,1074,551,12,741,1277,1278,217,1839,294,200,212,1014,383,1067,30,1257,279,93,786,96,219,639,932,983,45,633,687,67,726,11,162,297,1157,44,273,450,1689,1070,1407,198,1288,790,118,1221,310,655,285,167,115,870,156,217,444,518,1422,52,48,721,34,381,41,299,386,506,327,1201,262,5,42,448,246,145,1268,1047,944,428,29,1,265,381,767,481,409,1747,110,1238,1821,35,594,1,784,301,1228,72,1247,161,582,380,48,51,904,751,179,409,1219,238,453,42,248,99,94,10,387,257,70,1339,130,943,569,986,46,100,77,270,906,506,851,1,1550,983,192,351,233,798,1408,1029,215,95,240,1615,522,1285,392,133,794,431,195,959,504,679,50,837,58,964,342,1548,218,388,596,448,1377,617,442,210,412,355,1249,1094,1060,1718,131,248,4,301,809,980,166,80,282,1846,482,89,221,22,80,356,279,330,13,471,457,28,254,174,110,1742,26,633,1708,818,441,1578,1013,1312,897,458,11,696,1084,453,507,315,149,413,7,36,1000,458,181,286,300,132,1453,76,293,415,288,141,52,1190,1250,107,63,708,356,599,870,769,264,274 -------------------------------------------------------------------------------- /day3/main.go: -------------------------------------------------------------------------------- 1 | package day3 2 | 3 | import ( 4 | "math" 5 | "strings" 6 | ) 7 | 8 | func BinDiagnosePart1(input string) (_ int, err error) { 9 | var lines int 10 | var bits []int 11 | var line string 12 | for len(input) > 0 { 13 | i := strings.IndexByte(input, '\n') 14 | if i == -1 { 15 | break 16 | } 17 | line = input[0:i] 18 | input = input[i+1:] 19 | lines++ 20 | 21 | if len(bits) == 0 { 22 | bits = make([]int, len(line)) 23 | } 24 | 25 | for j, b := range line { 26 | if b == '1' { 27 | bits[j]++ 28 | } 29 | } 30 | } 31 | 32 | var epsilon, gamma int 33 | for i, b := range bits { 34 | if b > lines/2 { 35 | gamma += int(math.Pow(2, float64(len(bits)-i-1))) 36 | } else { 37 | epsilon += int(math.Pow(2, float64(len(bits)-i-1))) 38 | } 39 | } 40 | return gamma * epsilon, nil 41 | } 42 | 43 | func BinDiagnosePart2(input string) (_ int, err error) { 44 | var ox, co2 []string 45 | for len(input) > 0 { 46 | i := strings.IndexByte(input, '\n') 47 | if i == -1 { 48 | break 49 | } 50 | co2 = append(co2, input[0:i]) 51 | ox = append(ox, input[0:i]) 52 | input = input[i+1:] 53 | } 54 | 55 | return findRating(ox, true) * 56 | findRating(co2, false), nil 57 | } 58 | 59 | func findRating(numbers []string, common bool) int { 60 | var pos int 61 | nLen := float64(len(numbers)) 62 | for nLen > 1 { 63 | var bits float64 64 | for _, n := range numbers { 65 | if n[pos] == '1' { 66 | bits++ 67 | } 68 | } 69 | 70 | var filter uint8 71 | if common { 72 | filter = uint8('0') 73 | if bits >= nLen/2 { 74 | filter = '1' 75 | } 76 | } else { 77 | filter = uint8('0') 78 | if bits < nLen/2 { 79 | filter = '1' 80 | } 81 | } 82 | nLen = 0 83 | for _, n := range numbers { 84 | if n[pos] == filter { 85 | numbers[int(nLen)] = n 86 | nLen++ 87 | } 88 | } 89 | numbers = numbers[:int(nLen)] 90 | pos++ 91 | } 92 | 93 | return binToDecimal(numbers[0]) 94 | } 95 | 96 | func binToDecimal(binary string) (ret int) { 97 | for i, b := range binary { 98 | if b == '1' { 99 | ret += int(math.Pow(2, float64(len(binary)-i-1))) 100 | } 101 | } 102 | return ret 103 | } 104 | 105 | // BinDiagnosePart2_V2 is an optimized version of BinDiagnosePart2. 106 | // Pprof showed appends (grow slice) and looping numbers in findRating as main offenders. 107 | // Let's avoid appends with prealloc, and operate mostly on input. 108 | func BinDiagnosePart2_V2(input string) (_ int, err error) { 109 | var ( 110 | numLen = strings.IndexByte(input, '\n') 111 | numCount = len(input) / (numLen + 1) 112 | ) 113 | 114 | ox := make([]int, 0, numCount) 115 | co2 := make([]int, 0, numCount) 116 | 117 | // Shared loop for first iteration. 118 | var bits int 119 | for i := 0; i < numCount; i++ { 120 | // Add up? 121 | // Optimize if we see majority? 122 | if input[i*(numLen+1)] == '1' { 123 | bits++ 124 | } 125 | } 126 | 127 | filter := uint8('0') 128 | if bits > numCount/2 { 129 | filter = '1' 130 | } 131 | 132 | for i := 0; i < numCount; i++ { 133 | j := i * (numLen + 1) 134 | if input[j] == filter { 135 | ox = append(ox, j) 136 | } else { 137 | co2 = append(co2, j) 138 | } 139 | } 140 | 141 | return findRating_V2(input, numLen, ox, true) * findRating_V2(input, numLen, co2, false), nil 142 | } 143 | 144 | func findRating_V2(input string, numLen int, filtered []int, common bool) int { 145 | pos := 1 146 | fLen := float64(len(filtered)) 147 | for fLen > 1 { 148 | var bits float64 149 | for _, i := range filtered { 150 | if input[i+pos] == '1' { 151 | bits++ 152 | } 153 | } 154 | 155 | var filter uint8 156 | if common { 157 | filter = uint8('0') 158 | if bits >= fLen/2 { 159 | filter = '1' 160 | } 161 | } else { 162 | filter = uint8('0') 163 | if bits < fLen/2 { 164 | filter = '1' 165 | } 166 | } 167 | fLen = 0 168 | for _, i := range filtered { 169 | if input[i+pos] == filter { 170 | filtered[int(fLen)] = i 171 | fLen++ 172 | } 173 | } 174 | filtered = filtered[:int(fLen)] 175 | pos++ 176 | } 177 | 178 | return binToDecimal(input[filtered[0] : filtered[0]+numLen]) 179 | } 180 | -------------------------------------------------------------------------------- /day5/main_test.go: -------------------------------------------------------------------------------- 1 | package day5 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/bwplotka/efficiency-advent-2021/day2" 8 | "github.com/efficientgo/tools/core/pkg/testutil" 9 | ) 10 | 11 | func TestVentsOverlapPart1(t *testing.T) { 12 | for _, tcase := range []struct { 13 | input string 14 | expected int 15 | }{ 16 | { 17 | input: `0,9 -> 5,9 18 | 8,0 -> 0,8 19 | 9,4 -> 3,4 20 | 2,2 -> 2,1 21 | 7,0 -> 7,4 22 | 6,4 -> 2,0 23 | 0,9 -> 2,9 24 | 3,4 -> 1,4 25 | 0,0 -> 8,8 26 | 5,5 -> 8,2 27 | 2,2 -> 2,0`, // Extra test case over simple case in advent to check vertical line overlaps. 28 | expected: 7, 29 | }, 30 | { 31 | input: day2.ReadTestInput(t), 32 | expected: 4421, // Not 1786 and not 2714 (previous runs with bugs)(: 33 | }, 34 | } { 35 | t.Run("", func(t *testing.T) { 36 | input := strings.TrimSpace(tcase.input) + "\n" 37 | 38 | t.Run("VentsOverlapPart1", func(t *testing.T) { 39 | ans, err := VentsOverlapPart1(input) 40 | testutil.Ok(t, err) 41 | testutil.Equals(t, tcase.expected, ans) 42 | }) 43 | }) 44 | } 45 | } 46 | 47 | func TestVentsOverlapPart2(t *testing.T) { 48 | for _, tcase := range []struct { 49 | input string 50 | expected int 51 | }{ 52 | { 53 | input: `0,9 -> 5,9 54 | 8,0 -> 0,8 55 | 9,4 -> 3,4 56 | 2,2 -> 2,1 57 | 7,0 -> 7,4 58 | 6,4 -> 2,0 59 | 0,9 -> 2,9 60 | 3,4 -> 1,4 61 | 0,0 -> 8,8 62 | 5,5 -> 8,2 63 | 2,2 -> 2,0`, // Extra test case over simple case in advent to check vertical line overlaps. 64 | expected: 12 + 2, 65 | }, 66 | { 67 | input: day2.ReadTestInput(t), 68 | expected: 18674, 69 | }, 70 | } { 71 | t.Run("", func(t *testing.T) { 72 | input := strings.TrimSpace(tcase.input) + "\n" 73 | 74 | t.Run("VentsOverlapPart2", func(t *testing.T) { 75 | ans, err := VentsOverlapPart2(input) 76 | testutil.Ok(t, err) 77 | testutil.Equals(t, tcase.expected, ans) 78 | }) 79 | t.Run("VentsOverlapPart2_V2", func(t *testing.T) { 80 | ans, err := VentsOverlapPart2_V2(input) 81 | testutil.Ok(t, err) 82 | testutil.Equals(t, tcase.expected, ans) 83 | }) 84 | t.Run("VentsOverlapPart2_V3", func(t *testing.T) { 85 | ans, err := VentsOverlapPart2_V3(input) 86 | testutil.Ok(t, err) 87 | testutil.Equals(t, tcase.expected, ans) 88 | }) 89 | t.Run("VentsOverlapPart2_V4", func(t *testing.T) { 90 | ans, err := VentsOverlapPart2_V4(input) 91 | testutil.Ok(t, err) 92 | testutil.Equals(t, tcase.expected, ans) 93 | }) 94 | t.Run("VentsOverlapPart2_V5", func(t *testing.T) { 95 | ans, err := VentsOverlapPart2_V5(input) 96 | testutil.Ok(t, err) 97 | testutil.Equals(t, tcase.expected, ans) 98 | }) 99 | }) 100 | } 101 | } 102 | 103 | var Answer int 104 | 105 | // go test -count 5 -run '^$' -bench . -memprofile=v1.mem.pprof -cpuprofile=v1.cpu.pprof > v1.txt 106 | func BenchmarkVentsOverlapPart2(b *testing.B) { 107 | b.ReportAllocs() 108 | input := strings.TrimSpace(day2.ReadTestInput(b)) + "\n" 109 | 110 | b.ResetTimer() 111 | for i := 0; i < b.N; i++ { 112 | Answer, _ = VentsOverlapPart2_V5(input) 113 | } 114 | } 115 | 116 | func TestIntersection(t *testing.T) { 117 | for _, tcase := range []struct { 118 | a, b segment 119 | expected []point 120 | }{ 121 | // Horizontal. 122 | { 123 | a: newSegment(30, 50, 70, 50), 124 | b: newSegment(30, 50, 31, 50), 125 | expected: []point{{30, 50}, {31, 50}}, 126 | }, 127 | { 128 | a: newSegment(70, 50, 30, 50), 129 | b: newSegment(30, 50, 31, 50), 130 | expected: []point{{30, 50}, {31, 50}}, 131 | }, 132 | { 133 | a: newSegment(70, 50, 30, 50), 134 | b: newSegment(20, 50, 29, 50), 135 | }, 136 | { 137 | a: newSegment(70, 50, 30, 50), 138 | b: newSegment(20, 50, 30, 50), 139 | expected: []point{{30, 50}}, 140 | }, 141 | { 142 | a: newSegment(70, 50, 30, 50), 143 | b: newSegment(70, 50, 730, 50), 144 | expected: []point{{70, 50}}, 145 | }, 146 | { 147 | a: newSegment(70, 50, 30, 50), 148 | b: newSegment(71, 50, 730, 50), 149 | }, 150 | } { 151 | t.Run("", func(t *testing.T) { 152 | testutil.Equals(t, tcase.expected, tcase.a.intersectionPoints(&tcase.b)) 153 | }) 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/efficientgo/tools/core v0.0.0-20210829154005-c7bad8450208 h1:jIALuFymwBqVsF32JhgzVsbCB6QsWvXqhetn8QgyrZ4= 5 | github.com/efficientgo/tools/core v0.0.0-20210829154005-c7bad8450208/go.mod h1:OmVcnJopJL8d3X3sSXTiypGoUSgFq1aDGmlrdi9dn/M= 6 | github.com/go-gl/mathgl v1.0.0 h1:t9DznWJlXxxjeeKLIdovCOVJQk/GzDEL7h/h+Ro2B68= 7 | github.com/go-gl/mathgl v1.0.0/go.mod h1:yhpkQzEiH9yPyxDUGzkmgScbaBVlhC06qodikEM0ZwQ= 8 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 9 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 10 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 11 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 12 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 13 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 14 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 15 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 16 | github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= 17 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 18 | github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 19 | go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= 20 | go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= 21 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 22 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 23 | golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 24 | golang.org/x/image v0.0.0-20210216034530-4410531fe030 h1:lP9pYkih3DUSC641giIXa2XqfTIbbbRr0w2EOTA7wHA= 25 | golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 26 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= 27 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 28 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 29 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 30 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 31 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 32 | golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 33 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 34 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 35 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 36 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 37 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 38 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 39 | golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA= 40 | golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 41 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 42 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 43 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 44 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 45 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 46 | golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 47 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 48 | golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= 49 | golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= 50 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 51 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 52 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 53 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 54 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 55 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= 56 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 57 | -------------------------------------------------------------------------------- /day6/main.go: -------------------------------------------------------------------------------- 1 | package day6 2 | 3 | import ( 4 | "strconv" 5 | 6 | "github.com/pkg/errors" 7 | ) 8 | 9 | const ( 10 | daysToFish = 7 11 | delayDays = 2 // Days for new fish to be delayed for. 12 | ) 13 | 14 | func SimLanternfish(input string, days int) (_ int, err error) { 15 | var lanternfishes []int64 16 | for i := 0; i < len(input); { 17 | j := i 18 | 19 | for input[i] >= '0' && input[i] <= '9' { 20 | i++ 21 | } 22 | age, err := strconv.ParseInt(input[j:i], 10, 64) 23 | if err != nil { 24 | return 0, err 25 | } 26 | lanternfishes = append(lanternfishes, age) 27 | i++ 28 | } 29 | 30 | for d := 0; d < days; d++ { 31 | var fishesToAdd int 32 | for i := 0; i < len(lanternfishes); i++ { 33 | if lanternfishes[i] == 0 { 34 | lanternfishes[i] = daysToFish - 1 35 | fishesToAdd++ 36 | continue 37 | } 38 | lanternfishes[i]-- 39 | } 40 | for i := 0; i < fishesToAdd; i++ { 41 | lanternfishes = append(lanternfishes, daysToFish-1+delayDays) 42 | } 43 | } 44 | return len(lanternfishes), nil 45 | } 46 | 47 | func SimLanternfish_V2(input string, days int) (_ int64, err error) { 48 | fishesDuringDay := make([]int64, 7) 49 | for i := 0; i < len(input); { 50 | j := i 51 | 52 | for input[i] >= '0' && input[i] <= '9' { 53 | i++ 54 | } 55 | age, err := strconv.ParseInt(input[j:i], 10, 64) 56 | if err != nil { 57 | return 0, err 58 | } 59 | fishesDuringDay[age]++ 60 | i++ 61 | } 62 | 63 | index := 0 64 | var incubatedDay0, incubatedDay1 int64 65 | for d := 0; d < days; d++ { 66 | incubated := incubatedDay0 67 | incubatedDay0 = incubatedDay1 68 | // Let's create new fishes! 69 | incubatedDay1 = fishesDuringDay[index] 70 | // Incubated fishes can have 6 age. 71 | fishesDuringDay[index] += incubated 72 | 73 | if index == 6 { 74 | index = -1 75 | } 76 | index++ 77 | } 78 | 79 | return incubatedDay0 + incubatedDay1 + fishesDuringDay[0] + fishesDuringDay[1] + 80 | fishesDuringDay[2] + fishesDuringDay[3] + fishesDuringDay[4] + fishesDuringDay[5] + fishesDuringDay[6], nil 81 | } 82 | 83 | // ParseInt is 3-4x times faster than strconv.ParseInt or Atoi. 84 | func ParseInt(input string) (n int64, _ error) { 85 | factor := int64(1) 86 | k := 0 87 | if input[0] == '-' { 88 | factor *= -1 89 | k++ 90 | } 91 | 92 | for i := len(input) - 1; i >= k; i-- { 93 | if input[i] < '0' || input[i] > '9' { 94 | return 0, errors.Errorf("not a valid integerer: %v", input) 95 | } 96 | 97 | n += factor * int64(input[i]-'0') 98 | factor *= 10 99 | } 100 | return n, nil 101 | } 102 | 103 | func SimLanternfish_V3(input string, days int) (_ int64, err error) { 104 | fishesDuringDay := make([]int64, 7) 105 | for i := 0; i < len(input); { 106 | j := i 107 | 108 | for input[i] >= '0' && input[i] <= '9' { 109 | i++ 110 | } 111 | 112 | age, err := ParseInt(input[j:i]) 113 | if err != nil { 114 | return 0, err 115 | } 116 | 117 | fishesDuringDay[age]++ 118 | i++ 119 | } 120 | 121 | index := 0 122 | var incubatedDay0, incubatedDay1 int64 123 | for d := 0; d < days; d++ { 124 | incubated := incubatedDay0 125 | incubatedDay0 = incubatedDay1 126 | // Let's create new fishes! 127 | incubatedDay1 = fishesDuringDay[index] 128 | // Incubated fishes can have 6 age. 129 | fishesDuringDay[index] += incubated 130 | 131 | if index == 6 { 132 | index = -1 133 | } 134 | index++ 135 | } 136 | 137 | return incubatedDay0 + incubatedDay1 + fishesDuringDay[0] + fishesDuringDay[1] + 138 | fishesDuringDay[2] + fishesDuringDay[3] + fishesDuringDay[4] + fishesDuringDay[5] + fishesDuringDay[6], nil 139 | } 140 | 141 | func SimLanternfish_V4(input string, days int) (_ int64, err error) { 142 | fishesDuringDay := make([]int64, 7) 143 | for i := 0; i < len(input); { 144 | switch input[i] { 145 | case '0': 146 | fishesDuringDay[0]++ 147 | case '1': 148 | fishesDuringDay[1]++ 149 | case '2': 150 | fishesDuringDay[2]++ 151 | case '3': 152 | fishesDuringDay[3]++ 153 | case '4': 154 | fishesDuringDay[4]++ 155 | case '5': 156 | fishesDuringDay[5]++ 157 | case '6': 158 | fishesDuringDay[6]++ 159 | } 160 | i += 2 161 | } 162 | 163 | index := 0 164 | var incubatedDay0, incubatedDay1 int64 165 | for d := 0; d < days; d++ { 166 | incubated := incubatedDay0 167 | incubatedDay0 = incubatedDay1 168 | // Let's create new fishes! 169 | incubatedDay1 = fishesDuringDay[index] 170 | // Incubated fishes can have 6 age. 171 | fishesDuringDay[index] += incubated 172 | 173 | if index == 6 { 174 | index = -1 175 | } 176 | index++ 177 | } 178 | 179 | return incubatedDay0 + incubatedDay1 + fishesDuringDay[0] + fishesDuringDay[1] + 180 | fishesDuringDay[2] + fishesDuringDay[3] + fishesDuringDay[4] + fishesDuringDay[5] + fishesDuringDay[6], nil 181 | } 182 | 183 | func SimLanternfish_V5(input string, days int) (_ int64, err error) { 184 | fishesDuringDay := make([]int64, 7) 185 | for i := 0; i < len(input); { 186 | fishesDuringDay[int(input[i]-'0')]++ 187 | i += 2 188 | } 189 | 190 | index := 0 191 | var incubatedDay0, incubatedDay1 int64 192 | for d := 0; d < days; d++ { 193 | incubated := incubatedDay0 194 | incubatedDay0 = incubatedDay1 195 | // Let's create new fishes! 196 | incubatedDay1 = fishesDuringDay[index] 197 | // Incubated fishes can have 6 age. 198 | fishesDuringDay[index] += incubated 199 | 200 | if index == 6 { 201 | index = -1 202 | } 203 | index++ 204 | } 205 | 206 | return incubatedDay0 + incubatedDay1 + fishesDuringDay[0] + fishesDuringDay[1] + 207 | fishesDuringDay[2] + fishesDuringDay[3] + fishesDuringDay[4] + fishesDuringDay[5] + fishesDuringDay[6], nil 208 | } 209 | -------------------------------------------------------------------------------- /day2/main.go: -------------------------------------------------------------------------------- 1 | package day2 2 | 3 | import ( 4 | "io/ioutil" 5 | "strconv" 6 | "strings" 7 | "testing" 8 | "text/scanner" 9 | 10 | "github.com/efficientgo/tools/core/pkg/testutil" 11 | "github.com/pkg/errors" 12 | ) 13 | 14 | func ReadTestInput(t testing.TB) string { 15 | f, err := ioutil.ReadFile("input.txt") 16 | testutil.Ok(t, err) 17 | return string(f) 18 | } 19 | 20 | func DivePart1(input string) (_ int, err error) { 21 | s := scanner.Scanner{ 22 | Error: func(s *scanner.Scanner, msg string) { 23 | err = errors.New(msg) 24 | }, 25 | } 26 | s.Init(strings.NewReader(input)) 27 | 28 | var forward, depth int 29 | for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { 30 | dir := s.TokenText() 31 | 32 | tok = s.Scan() 33 | if tok == scanner.EOF { 34 | return 0, errors.Errorf("expected digit after %v", dir) 35 | } 36 | 37 | digit, err := strconv.ParseInt(s.TokenText(), 10, 64) 38 | if err != nil { 39 | return 0, err 40 | } 41 | 42 | switch dir { 43 | case "forward": 44 | forward += int(digit) 45 | case "down": 46 | depth += int(digit) 47 | case "up": 48 | depth -= int(digit) 49 | default: 50 | return 0, errors.Errorf("unknown direction %v", dir) 51 | } 52 | } 53 | 54 | return depth * forward, nil 55 | } 56 | 57 | func DivePart2(input string) (_ int, err error) { 58 | s := scanner.Scanner{ 59 | Error: func(s *scanner.Scanner, msg string) { 60 | err = errors.New(msg) 61 | }, 62 | } 63 | s.Init(strings.NewReader(input)) 64 | 65 | var aim, forward, depth int 66 | for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { 67 | dir := s.TokenText() 68 | 69 | tok = s.Scan() 70 | if tok == scanner.EOF { 71 | return 0, errors.Errorf("expected digit after %v", dir) 72 | } 73 | 74 | digit, err := strconv.ParseInt(s.TokenText(), 10, 64) 75 | if err != nil { 76 | return 0, err 77 | } 78 | 79 | switch dir { 80 | case "forward": 81 | forward += int(digit) 82 | depth += aim * int(digit) 83 | case "down": 84 | aim += int(digit) 85 | case "up": 86 | aim -= int(digit) 87 | default: 88 | return 0, errors.Errorf("unknown direction %v", dir) 89 | } 90 | } 91 | 92 | return depth * forward, nil 93 | } 94 | 95 | // DivePart2_V2 is optimized version of DivePart2_V1 for latency. 96 | // Scanner is quite bad, let's reimplement using IndexByte as in https://felixge.de/2021/12/01/advent-of-go-profiling-2021-day-1-1/. 97 | func DivePart2_V2(input string) (_ int, err error) { 98 | var aim, forward, depth int 99 | 100 | var line string 101 | for len(input) > 0 { 102 | i := strings.IndexByte(input, '\n') 103 | if i == -1 { 104 | break 105 | } 106 | line = input[0:i] 107 | input = input[i+1:] 108 | 109 | // Last char is digit. 110 | digit, err := strconv.ParseInt(string(line[len(line)-1]), 10, 64) 111 | if err != nil { 112 | return 0, err 113 | } 114 | 115 | switch line[0] { 116 | case 'f': 117 | forward += int(digit) 118 | depth += aim * int(digit) 119 | case 'd': 120 | aim += int(digit) 121 | case 'u': 122 | aim -= int(digit) 123 | default: 124 | return 0, errors.Errorf("unknown direction %v", line) 125 | } 126 | } 127 | return depth * forward, nil 128 | } 129 | 130 | func parseDigit(val uint8) (intval int, _ error) { 131 | if val < '0' || val > '9' { 132 | return 0, errors.Errorf("bad int: %q", val) 133 | } 134 | return int(val - '0'), nil 135 | } 136 | 137 | // DivePart2_V3 is optimized version of DivePart2_V2 for latency. 138 | // mallogc GC and int parsing are main offendant. Let's reduce allocs and optimize int parsing. 139 | // This solution has 0 heap allocs. 140 | func DivePart2_V3(input string) (_ int, err error) { 141 | var aim, forward, depth int 142 | var line string 143 | for len(input) > 0 { 144 | i := strings.IndexByte(input, '\n') 145 | if i == -1 { 146 | break 147 | } 148 | line = input[0:i] 149 | input = input[i+1:] 150 | 151 | // Last char is digit. 152 | digit, err := parseDigit(line[len(line)-1]) 153 | if err != nil { 154 | return 0, err 155 | } 156 | 157 | switch line[0] { 158 | case 'f': 159 | forward += digit 160 | depth += aim * digit 161 | case 'd': 162 | aim += digit 163 | case 'u': 164 | aim -= digit 165 | default: 166 | return 0, errors.Errorf("unknown direction %v", line) 167 | } 168 | } 169 | return depth * forward, nil 170 | } 171 | 172 | // DivePart2_V4 is optimized version of DivePart2_V3 for latency. 173 | // IndexByte were main offendants. 174 | // This is still SLOWER than index Byte. V3 is the fastest. 175 | func DivePart2_V4(input string) (_ int, err error) { 176 | var aim, forward, depth, lastNewLineOffset int 177 | var line string 178 | for i, c := range input { 179 | if c != '\n' { 180 | continue 181 | } 182 | 183 | line = input[lastNewLineOffset:i] 184 | lastNewLineOffset = i + 1 185 | 186 | // Last char is digit. 187 | digit, err := parseDigit(line[len(line)-1]) 188 | if err != nil { 189 | return 0, err 190 | } 191 | 192 | switch line[0] { 193 | case 'f': 194 | forward += digit 195 | depth += aim * digit 196 | case 'd': 197 | aim += digit 198 | case 'u': 199 | aim -= digit 200 | default: 201 | return 0, errors.Errorf("unknown direction %v", line) 202 | } 203 | } 204 | return depth * forward, nil 205 | } 206 | 207 | // DivePart2_V5 is optimized version of DivePart2_V3 for latency. 208 | // We can optimize the digit parsing further. 209 | func DivePart2_V5(input string) (_ int, err error) { 210 | var aim, forward, depth int 211 | var line string 212 | for len(input) > 0 { 213 | i := strings.IndexByte(input, '\n') 214 | if i == -1 { 215 | break 216 | } 217 | line = input[0:i] 218 | input = input[i+1:] 219 | 220 | // Last char is digit. 221 | digit := int(line[len(line)-1] - '0') 222 | 223 | switch line[0] { 224 | case 'f': 225 | forward += digit 226 | depth += aim * digit 227 | case 'd': 228 | aim += digit 229 | case 'u': 230 | aim -= digit 231 | default: 232 | return 0, errors.Errorf("unknown direction %v", line) 233 | } 234 | } 235 | return depth * forward, nil 236 | } 237 | -------------------------------------------------------------------------------- /day19/main_test.go: -------------------------------------------------------------------------------- 1 | package day19 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/bwplotka/efficiency-advent-2021/day2" 8 | "github.com/efficientgo/tools/core/pkg/testutil" 9 | ) 10 | 11 | func TestHowManyBeaconsPart1(t *testing.T) { 12 | for _, tcase := range []struct { 13 | input string 14 | expected int64 15 | overlapThreshold int 16 | }{ 17 | { 18 | overlapThreshold: 12, 19 | input: `--- scanner 0 --- 20 | 404,-588,-901 21 | 528,-643,409 22 | -838,591,734 23 | 390,-675,-793 24 | -537,-823,-458 25 | -485,-357,347 26 | -345,-311,381 27 | -661,-816,-575 28 | -876,649,763 29 | -618,-824,-621 30 | 553,345,-567 31 | 474,580,667 32 | -447,-329,318 33 | -584,868,-557 34 | 544,-627,-890 35 | 564,392,-477 36 | 455,729,728 37 | -892,524,684 38 | -689,845,-530 39 | 423,-701,434 40 | 7,-33,-71 41 | 630,319,-379 42 | 443,580,662 43 | -789,900,-551 44 | 459,-707,401 45 | 46 | --- scanner 1 --- 47 | 686,422,578 48 | 605,423,415 49 | 515,917,-361 50 | -336,658,858 51 | 95,138,22 52 | -476,619,847 53 | -340,-569,-846 54 | 567,-361,727 55 | -460,603,-452 56 | 669,-402,600 57 | 729,430,532 58 | -500,-761,534 59 | -322,571,750 60 | -466,-666,-811 61 | -429,-592,574 62 | -355,545,-477 63 | 703,-491,-529 64 | -328,-685,520 65 | 413,935,-424 66 | -391,539,-444 67 | 586,-435,557 68 | -364,-763,-893 69 | 807,-499,-711 70 | 755,-354,-619 71 | 553,889,-390 72 | 73 | --- scanner 2 --- 74 | 649,640,665 75 | 682,-795,504 76 | -784,533,-524 77 | -644,584,-595 78 | -588,-843,648 79 | -30,6,44 80 | -674,560,763 81 | 500,723,-460 82 | 609,671,-379 83 | -555,-800,653 84 | -675,-892,-343 85 | 697,-426,-610 86 | 578,704,681 87 | 493,664,-388 88 | -671,-858,530 89 | -667,343,800 90 | 571,-461,-707 91 | -138,-166,112 92 | -889,563,-600 93 | 646,-828,498 94 | 640,759,510 95 | -630,509,768 96 | -681,-892,-333 97 | 673,-379,-804 98 | -742,-814,-386 99 | 577,-820,562 100 | 101 | --- scanner 3 --- 102 | -589,542,597 103 | 605,-692,669 104 | -500,565,-823 105 | -660,373,557 106 | -458,-679,-417 107 | -488,449,543 108 | -626,468,-788 109 | 338,-750,-386 110 | 528,-832,-391 111 | 562,-778,733 112 | -938,-730,414 113 | 543,643,-506 114 | -524,371,-870 115 | 407,773,750 116 | -104,29,83 117 | 378,-903,-323 118 | -778,-728,485 119 | 426,699,580 120 | -438,-605,-362 121 | -469,-447,-387 122 | 509,732,623 123 | 647,635,-688 124 | -868,-804,481 125 | 614,-800,639 126 | 595,780,-596 127 | 128 | --- scanner 4 --- 129 | 727,592,562 130 | -293,-554,779 131 | 441,611,-461 132 | -714,465,-776 133 | -743,427,-804 134 | -660,-479,-426 135 | 832,-632,460 136 | 927,-485,-438 137 | 408,393,-506 138 | 466,436,-512 139 | 110,16,151 140 | -258,-428,682 141 | -393,719,612 142 | -211,-452,876 143 | 808,-476,-593 144 | -575,615,604 145 | -485,667,467 146 | -680,325,-822 147 | -627,-443,-432 148 | 872,-547,-609 149 | 833,512,582 150 | 807,604,487 151 | 839,-516,451 152 | 891,-625,532 153 | -652,-548,-490 154 | 30,-46,-14`, 155 | expected: 79, 156 | }, 157 | { 158 | overlapThreshold: 12, 159 | input: day2.ReadTestInput(t), // 31 scanners. 160 | expected: 381, 161 | }, 162 | } { 163 | t.Run("", func(t *testing.T) { 164 | input := strings.TrimSpace(tcase.input) + "\n" 165 | 166 | t.Run("HowManyBeaconsPart1", func(t *testing.T) { 167 | ans, err := HowManyBeaconsPart1(input, tcase.overlapThreshold) 168 | testutil.Ok(t, err) 169 | testutil.Equals(t, tcase.expected, int64(ans)) 170 | }) 171 | }) 172 | } 173 | } 174 | 175 | func TestManhattanDistPart2(t *testing.T) { 176 | for _, tcase := range []struct { 177 | input string 178 | expected int64 179 | overlapThreshold int 180 | }{ 181 | { 182 | overlapThreshold: 12, 183 | input: `--- scanner 0 --- 184 | 404,-588,-901 185 | 528,-643,409 186 | -838,591,734 187 | 390,-675,-793 188 | -537,-823,-458 189 | -485,-357,347 190 | -345,-311,381 191 | -661,-816,-575 192 | -876,649,763 193 | -618,-824,-621 194 | 553,345,-567 195 | 474,580,667 196 | -447,-329,318 197 | -584,868,-557 198 | 544,-627,-890 199 | 564,392,-477 200 | 455,729,728 201 | -892,524,684 202 | -689,845,-530 203 | 423,-701,434 204 | 7,-33,-71 205 | 630,319,-379 206 | 443,580,662 207 | -789,900,-551 208 | 459,-707,401 209 | 210 | --- scanner 1 --- 211 | 686,422,578 212 | 605,423,415 213 | 515,917,-361 214 | -336,658,858 215 | 95,138,22 216 | -476,619,847 217 | -340,-569,-846 218 | 567,-361,727 219 | -460,603,-452 220 | 669,-402,600 221 | 729,430,532 222 | -500,-761,534 223 | -322,571,750 224 | -466,-666,-811 225 | -429,-592,574 226 | -355,545,-477 227 | 703,-491,-529 228 | -328,-685,520 229 | 413,935,-424 230 | -391,539,-444 231 | 586,-435,557 232 | -364,-763,-893 233 | 807,-499,-711 234 | 755,-354,-619 235 | 553,889,-390 236 | 237 | --- scanner 2 --- 238 | 649,640,665 239 | 682,-795,504 240 | -784,533,-524 241 | -644,584,-595 242 | -588,-843,648 243 | -30,6,44 244 | -674,560,763 245 | 500,723,-460 246 | 609,671,-379 247 | -555,-800,653 248 | -675,-892,-343 249 | 697,-426,-610 250 | 578,704,681 251 | 493,664,-388 252 | -671,-858,530 253 | -667,343,800 254 | 571,-461,-707 255 | -138,-166,112 256 | -889,563,-600 257 | 646,-828,498 258 | 640,759,510 259 | -630,509,768 260 | -681,-892,-333 261 | 673,-379,-804 262 | -742,-814,-386 263 | 577,-820,562 264 | 265 | --- scanner 3 --- 266 | -589,542,597 267 | 605,-692,669 268 | -500,565,-823 269 | -660,373,557 270 | -458,-679,-417 271 | -488,449,543 272 | -626,468,-788 273 | 338,-750,-386 274 | 528,-832,-391 275 | 562,-778,733 276 | -938,-730,414 277 | 543,643,-506 278 | -524,371,-870 279 | 407,773,750 280 | -104,29,83 281 | 378,-903,-323 282 | -778,-728,485 283 | 426,699,580 284 | -438,-605,-362 285 | -469,-447,-387 286 | 509,732,623 287 | 647,635,-688 288 | -868,-804,481 289 | 614,-800,639 290 | 595,780,-596 291 | 292 | --- scanner 4 --- 293 | 727,592,562 294 | -293,-554,779 295 | 441,611,-461 296 | -714,465,-776 297 | -743,427,-804 298 | -660,-479,-426 299 | 832,-632,460 300 | 927,-485,-438 301 | 408,393,-506 302 | 466,436,-512 303 | 110,16,151 304 | -258,-428,682 305 | -393,719,612 306 | -211,-452,876 307 | 808,-476,-593 308 | -575,615,604 309 | -485,667,467 310 | -680,325,-822 311 | -627,-443,-432 312 | 872,-547,-609 313 | 833,512,582 314 | 807,604,487 315 | 839,-516,451 316 | 891,-625,532 317 | -652,-548,-490 318 | 30,-46,-14`, 319 | expected: 3621, 320 | }, 321 | { 322 | overlapThreshold: 12, 323 | input: day2.ReadTestInput(t), // 31 scanners. 324 | expected: 12201, 325 | }, 326 | } { 327 | t.Run("", func(t *testing.T) { 328 | input := strings.TrimSpace(tcase.input) + "\n" 329 | 330 | t.Run("ManhattanDistPart2", func(t *testing.T) { 331 | ans, err := ManhattanDistPart2(input, tcase.overlapThreshold) 332 | testutil.Ok(t, err) 333 | testutil.Equals(t, tcase.expected, int64(ans)) 334 | }) 335 | }) 336 | } 337 | } 338 | 339 | var Answer int 340 | 341 | // go test -count 5 -run '^$' -bench . -memprofile=v1.mem.pprof -cpuprofile=v1.cpu.pprof > v1.txt 342 | func BenchmarkManhattanDistPart2(b *testing.B) { 343 | b.ReportAllocs() 344 | input := strings.TrimSpace(day2.ReadTestInput(b)) + "\n" 345 | 346 | b.ResetTimer() 347 | for i := 0; i < b.N; i++ { 348 | Answer, _ = ManhattanDistPart2(input, 12) 349 | } 350 | } 351 | -------------------------------------------------------------------------------- /day4/input.txt: -------------------------------------------------------------------------------- 1 | 94,21,58,16,4,1,44,6,17,48,20,92,55,36,40,63,62,2,47,7,46,72,85,24,66,49,34,56,98,41,84,23,86,64,28,90,39,97,73,81,12,69,35,26,75,8,32,77,52,50,5,96,14,31,70,60,29,71,9,68,19,65,99,57,54,61,33,91,27,78,43,95,42,3,88,51,53,30,89,87,93,74,18,15,80,38,82,79,0,22,13,67,59,11,83,76,10,37,25,45 2 | 3 | 49 74 83 34 40 4 | 87 16 57 75 3 5 | 68 94 77 78 89 6 | 56 38 29 26 60 7 | 41 42 45 19 1 8 | 9 | 42 35 10 20 9 10 | 49 39 40 41 73 11 | 3 48 91 81 88 12 | 59 55 82 58 71 13 | 61 51 17 26 72 14 | 15 | 31 49 21 84 83 16 | 18 86 53 75 29 17 | 85 2 51 76 52 18 | 48 28 24 69 12 19 | 5 87 67 95 82 20 | 21 | 54 21 0 63 13 22 | 84 29 27 12 82 23 | 55 86 33 90 95 24 | 72 96 24 88 37 25 | 38 51 35 46 50 26 | 27 | 24 1 23 62 97 28 | 53 72 99 59 81 29 | 54 26 93 63 20 30 | 79 41 2 86 98 31 | 84 13 87 33 96 32 | 33 | 36 85 51 32 84 34 | 41 70 65 86 73 35 | 94 28 80 81 59 36 | 96 82 7 10 83 37 | 8 21 29 91 16 38 | 39 | 56 36 87 10 35 40 | 8 90 37 22 96 41 | 24 82 30 50 86 42 | 70 52 55 51 57 43 | 26 41 61 46 65 44 | 45 | 6 28 71 21 50 46 | 61 92 19 17 79 47 | 85 69 63 32 41 48 | 8 36 37 38 83 49 | 13 45 88 77 78 50 | 51 | 55 61 34 72 65 52 | 8 92 39 27 86 53 | 69 16 66 94 53 54 | 35 41 50 1 42 55 | 31 43 3 85 59 56 | 57 | 55 78 47 85 50 58 | 80 15 98 42 63 59 | 2 68 37 24 45 60 | 8 99 33 89 20 61 | 35 28 60 5 34 62 | 63 | 76 4 33 91 0 64 | 98 97 39 51 5 65 | 43 86 58 63 93 66 | 16 67 88 50 19 67 | 2 68 17 26 89 68 | 69 | 20 57 93 41 35 70 | 76 7 14 58 54 71 | 85 51 24 40 38 72 | 47 13 82 29 10 73 | 9 21 8 87 17 74 | 75 | 65 82 87 15 49 76 | 43 37 53 6 93 77 | 89 83 66 84 33 78 | 58 41 44 8 91 79 | 23 1 73 5 26 80 | 81 | 2 27 51 80 5 82 | 88 17 32 75 0 83 | 10 38 78 56 25 84 | 48 11 63 73 50 85 | 57 9 67 86 31 86 | 87 | 35 47 63 9 13 88 | 12 14 82 37 32 89 | 49 74 79 90 10 90 | 22 50 41 46 15 91 | 39 56 19 42 21 92 | 93 | 6 48 3 2 95 94 | 57 40 86 4 21 95 | 1 23 65 76 90 96 | 47 63 29 58 49 97 | 77 36 71 55 83 98 | 99 | 31 1 98 47 99 100 | 85 56 81 29 76 101 | 14 46 12 62 83 102 | 86 45 74 73 32 103 | 17 9 59 26 21 104 | 105 | 89 72 83 48 3 106 | 81 34 27 42 41 107 | 90 22 95 85 36 108 | 44 45 31 73 57 109 | 19 60 50 29 75 110 | 111 | 93 2 26 35 39 112 | 91 7 85 69 62 113 | 55 4 27 57 10 114 | 92 44 30 73 22 115 | 6 58 16 36 9 116 | 117 | 6 42 55 24 8 118 | 19 43 2 21 90 119 | 99 89 48 60 58 120 | 72 87 1 66 63 121 | 53 16 71 20 28 122 | 123 | 98 82 4 29 95 124 | 40 63 71 64 96 125 | 41 76 93 58 66 126 | 30 36 28 59 74 127 | 92 1 91 39 65 128 | 129 | 96 78 45 44 3 130 | 53 29 75 51 64 131 | 19 84 41 30 60 132 | 86 47 99 71 42 133 | 95 23 40 43 22 134 | 135 | 70 26 4 34 15 136 | 66 51 12 16 36 137 | 28 11 77 61 87 138 | 27 75 38 65 31 139 | 6 33 56 10 76 140 | 141 | 9 74 75 61 55 142 | 63 49 29 48 44 143 | 65 12 45 17 31 144 | 43 71 88 96 57 145 | 20 42 34 99 21 146 | 147 | 15 11 32 26 51 148 | 23 20 19 14 82 149 | 75 60 0 18 59 150 | 30 66 40 57 47 151 | 77 44 37 80 61 152 | 153 | 3 40 26 25 33 154 | 18 80 72 28 16 155 | 9 46 50 91 93 156 | 88 13 52 1 65 157 | 70 27 78 43 39 158 | 159 | 35 77 7 49 72 160 | 59 8 87 60 15 161 | 38 81 71 24 20 162 | 50 54 94 31 75 163 | 68 2 11 27 64 164 | 165 | 45 39 55 51 30 166 | 56 0 2 28 10 167 | 43 32 46 80 98 168 | 15 82 17 92 89 169 | 73 62 93 33 40 170 | 171 | 21 94 54 29 24 172 | 40 35 73 43 77 173 | 80 14 2 76 31 174 | 17 11 8 42 45 175 | 46 78 59 99 55 176 | 177 | 92 24 9 39 4 178 | 55 20 17 65 99 179 | 67 86 72 6 38 180 | 53 51 27 63 93 181 | 48 95 83 66 85 182 | 183 | 26 68 60 15 41 184 | 32 55 33 71 63 185 | 92 22 70 20 78 186 | 85 89 29 27 84 187 | 98 91 36 23 6 188 | 189 | 77 71 11 12 24 190 | 98 85 36 29 35 191 | 80 51 88 25 81 192 | 23 9 33 61 48 193 | 5 66 94 54 10 194 | 195 | 89 67 34 98 57 196 | 4 20 80 83 28 197 | 63 77 66 5 47 198 | 8 36 43 45 41 199 | 81 18 90 91 15 200 | 201 | 20 93 58 27 99 202 | 45 47 59 9 23 203 | 25 71 14 48 62 204 | 95 7 69 41 90 205 | 53 1 10 98 70 206 | 207 | 1 4 67 24 48 208 | 53 88 77 70 86 209 | 99 30 23 61 27 210 | 82 95 73 37 78 211 | 47 92 13 94 0 212 | 213 | 94 8 19 74 24 214 | 10 60 2 65 18 215 | 31 22 16 25 32 216 | 75 4 86 55 26 217 | 93 47 98 43 44 218 | 219 | 58 39 34 69 79 220 | 88 78 85 84 23 221 | 89 63 29 28 40 222 | 37 83 56 74 32 223 | 24 73 61 7 35 224 | 225 | 46 35 27 49 81 226 | 92 41 33 64 5 227 | 13 6 96 66 85 228 | 76 3 19 17 2 229 | 82 30 88 0 39 230 | 231 | 46 2 1 82 72 232 | 9 14 36 95 70 233 | 56 65 13 35 28 234 | 38 59 62 21 19 235 | 99 77 16 52 8 236 | 237 | 74 94 50 56 7 238 | 60 18 83 87 21 239 | 85 42 64 53 40 240 | 43 30 67 41 68 241 | 32 63 97 82 9 242 | 243 | 6 16 58 70 86 244 | 42 28 51 38 54 245 | 88 46 90 83 36 246 | 65 24 95 63 52 247 | 94 25 84 5 71 248 | 249 | 10 84 5 18 34 250 | 76 46 82 49 98 251 | 74 99 29 11 41 252 | 42 92 20 64 39 253 | 91 85 79 32 52 254 | 255 | 67 68 72 43 14 256 | 86 5 24 40 70 257 | 57 12 92 0 98 258 | 60 58 15 13 2 259 | 17 51 6 3 74 260 | 261 | 50 27 68 12 80 262 | 79 26 17 59 86 263 | 57 29 82 70 71 264 | 93 6 78 39 24 265 | 72 53 23 49 98 266 | 267 | 69 27 19 18 54 268 | 6 38 34 41 49 269 | 17 94 93 25 86 270 | 1 45 60 44 62 271 | 31 72 59 83 36 272 | 273 | 45 33 42 91 39 274 | 6 77 32 21 27 275 | 9 92 30 2 43 276 | 89 79 86 11 83 277 | 23 94 76 65 1 278 | 279 | 78 16 22 80 75 280 | 42 61 8 35 93 281 | 62 59 66 79 13 282 | 44 77 7 87 68 283 | 74 14 52 65 19 284 | 285 | 60 24 88 7 29 286 | 95 33 36 81 71 287 | 67 39 2 49 37 288 | 78 25 28 35 93 289 | 20 3 12 99 6 290 | 291 | 49 99 87 89 85 292 | 86 63 42 38 68 293 | 46 19 94 60 65 294 | 18 51 8 0 3 295 | 64 77 23 35 16 296 | 297 | 95 22 33 57 64 298 | 12 37 75 6 74 299 | 76 16 86 15 48 300 | 70 99 24 19 52 301 | 47 65 46 32 8 302 | 303 | 82 71 28 64 46 304 | 88 90 85 69 84 305 | 33 86 7 27 10 306 | 45 48 0 31 99 307 | 37 4 77 29 49 308 | 309 | 69 33 73 50 26 310 | 24 41 15 91 78 311 | 95 47 70 23 19 312 | 80 14 60 56 3 313 | 55 58 8 43 16 314 | 315 | 64 76 70 0 4 316 | 58 26 95 88 53 317 | 1 45 50 97 93 318 | 30 65 31 6 81 319 | 12 11 74 68 94 320 | 321 | 13 14 60 87 56 322 | 69 3 64 29 57 323 | 24 86 78 21 15 324 | 33 25 70 67 38 325 | 22 73 11 50 96 326 | 327 | 73 15 22 78 63 328 | 48 51 6 39 20 329 | 11 91 12 0 65 330 | 2 90 19 64 43 331 | 42 89 71 10 31 332 | 333 | 48 5 78 25 89 334 | 82 57 32 80 60 335 | 13 21 88 76 65 336 | 38 72 53 4 51 337 | 0 31 20 17 36 338 | 339 | 41 71 27 24 58 340 | 3 54 43 36 75 341 | 7 1 39 59 95 342 | 99 97 18 40 96 343 | 50 61 49 69 31 344 | 345 | 58 93 37 23 25 346 | 88 81 45 50 33 347 | 76 97 4 21 72 348 | 56 2 98 78 51 349 | 32 17 19 29 6 350 | 351 | 73 91 87 49 74 352 | 99 45 24 76 77 353 | 44 67 3 60 27 354 | 36 62 94 96 57 355 | 0 16 48 54 92 356 | 357 | 90 7 66 65 1 358 | 27 42 3 11 26 359 | 63 95 69 53 29 360 | 43 12 52 37 96 361 | 84 13 41 36 35 362 | 363 | 10 5 54 4 16 364 | 51 17 22 49 3 365 | 86 65 40 58 47 366 | 71 69 20 7 98 367 | 75 57 97 74 35 368 | 369 | 31 53 17 88 12 370 | 74 39 59 82 68 371 | 46 23 13 28 76 372 | 0 89 48 43 37 373 | 34 50 86 19 66 374 | 375 | 70 82 88 32 9 376 | 7 15 38 56 62 377 | 91 25 49 78 77 378 | 40 42 44 79 18 379 | 1 84 28 73 97 380 | 381 | 67 38 62 93 81 382 | 1 63 17 86 90 383 | 55 66 6 39 13 384 | 72 80 5 70 11 385 | 30 71 96 14 73 386 | 387 | 73 29 93 64 48 388 | 9 41 70 57 46 389 | 33 92 78 82 91 390 | 90 4 87 43 56 391 | 83 28 59 85 8 392 | 393 | 23 99 26 4 56 394 | 79 39 31 82 92 395 | 17 20 44 70 35 396 | 48 71 95 53 1 397 | 97 24 41 91 87 398 | 399 | 93 61 95 53 27 400 | 54 49 74 16 82 401 | 30 17 59 64 79 402 | 4 28 36 9 38 403 | 58 80 44 85 45 404 | 405 | 92 28 76 97 45 406 | 93 34 3 75 81 407 | 15 14 67 64 80 408 | 1 68 84 83 25 409 | 19 20 56 78 58 410 | 411 | 98 38 94 26 30 412 | 32 66 59 41 52 413 | 40 37 73 18 39 414 | 58 4 55 19 27 415 | 62 69 51 44 77 416 | 417 | 48 4 3 60 11 418 | 81 76 10 0 80 419 | 41 93 25 53 49 420 | 14 21 85 38 45 421 | 5 89 12 98 74 422 | 423 | 10 18 21 71 94 424 | 14 64 44 83 47 425 | 78 11 5 29 6 426 | 56 36 85 73 26 427 | 62 30 35 7 39 428 | 429 | 32 31 71 52 12 430 | 62 35 44 95 68 431 | 67 29 15 85 9 432 | 27 72 58 21 93 433 | 11 54 40 41 37 434 | 435 | 7 45 74 17 9 436 | 99 16 84 63 61 437 | 44 21 59 69 66 438 | 11 39 80 19 72 439 | 89 58 81 42 87 440 | 441 | 91 84 78 7 95 442 | 24 3 85 20 16 443 | 29 38 52 41 21 444 | 37 23 56 73 54 445 | 11 47 5 65 51 446 | 447 | 93 94 24 74 88 448 | 9 72 82 6 73 449 | 92 12 97 34 71 450 | 35 3 0 2 19 451 | 55 38 67 26 50 452 | 453 | 56 22 52 96 72 454 | 21 67 65 37 64 455 | 99 76 51 39 24 456 | 90 4 57 75 47 457 | 40 32 44 83 34 458 | 459 | 90 58 56 43 94 460 | 99 61 95 18 72 461 | 86 20 47 89 53 462 | 97 38 0 39 93 463 | 85 98 62 21 5 464 | 465 | 68 20 23 1 63 466 | 37 97 47 30 70 467 | 66 35 46 36 2 468 | 29 87 82 59 10 469 | 12 5 39 73 99 470 | 471 | 1 82 87 52 42 472 | 65 74 46 92 56 473 | 25 29 26 34 51 474 | 20 10 39 81 32 475 | 12 11 89 18 27 476 | 477 | 94 36 29 72 10 478 | 34 47 77 83 18 479 | 38 76 6 48 97 480 | 41 90 61 69 78 481 | 14 74 66 55 33 482 | 483 | 78 25 8 24 74 484 | 60 53 80 50 48 485 | 66 92 55 17 3 486 | 77 95 18 35 34 487 | 5 11 70 1 82 488 | 489 | 58 91 5 63 35 490 | 99 37 76 90 73 491 | 20 50 67 61 17 492 | 13 62 54 32 21 493 | 47 30 94 68 49 494 | 495 | 16 1 38 84 56 496 | 53 79 14 17 47 497 | 23 97 61 24 65 498 | 83 89 4 29 90 499 | 94 57 50 22 31 500 | 501 | 9 50 63 65 17 502 | 8 22 66 4 19 503 | 89 71 24 70 68 504 | 47 1 56 6 40 505 | 62 46 75 43 37 506 | 507 | 2 15 10 18 14 508 | 45 34 35 77 20 509 | 76 55 48 28 26 510 | 80 65 68 19 84 511 | 1 94 40 85 11 512 | 513 | 80 47 69 78 37 514 | 88 10 95 86 96 515 | 28 14 98 20 35 516 | 16 6 8 50 38 517 | 51 26 53 9 54 518 | 519 | 93 75 53 1 16 520 | 30 66 76 19 51 521 | 69 22 28 31 7 522 | 15 36 96 17 97 523 | 92 23 45 26 48 524 | 525 | 96 13 63 81 65 526 | 39 47 48 5 31 527 | 64 20 95 61 60 528 | 4 83 55 97 14 529 | 92 45 88 99 79 530 | 531 | 11 35 56 27 50 532 | 85 40 71 88 99 533 | 59 39 84 44 43 534 | 22 19 10 12 98 535 | 13 7 76 23 21 536 | 537 | 94 67 79 35 47 538 | 83 77 3 11 15 539 | 74 10 70 14 44 540 | 76 5 80 46 71 541 | 20 36 53 88 40 542 | 543 | 34 24 12 63 47 544 | 32 96 67 40 82 545 | 42 7 87 61 10 546 | 70 14 65 88 74 547 | 92 9 53 60 56 548 | 549 | 43 38 91 30 72 550 | 20 3 64 80 32 551 | 90 37 28 4 14 552 | 96 11 6 84 68 553 | 58 60 45 61 47 554 | 555 | 45 11 65 41 46 556 | 29 33 56 26 3 557 | 21 90 42 96 27 558 | 94 17 32 92 25 559 | 43 99 36 70 87 560 | 561 | 52 99 88 76 66 562 | 75 81 48 2 96 563 | 55 59 39 97 34 564 | 77 37 6 82 47 565 | 64 29 32 19 86 566 | 567 | 4 20 57 61 8 568 | 28 33 42 30 86 569 | 34 65 14 40 46 570 | 43 49 37 22 39 571 | 71 18 11 85 92 572 | 573 | 68 51 39 93 1 574 | 9 82 35 67 81 575 | 3 12 29 6 83 576 | 58 73 97 26 20 577 | 2 28 99 64 77 578 | 579 | 88 41 91 98 89 580 | 82 1 37 10 14 581 | 52 44 90 34 21 582 | 76 27 43 54 49 583 | 31 84 46 57 77 584 | 585 | 73 99 79 76 43 586 | 82 17 14 68 87 587 | 39 53 21 7 81 588 | 94 45 35 48 32 589 | 67 49 62 63 23 590 | 591 | 99 0 85 12 83 592 | 30 45 67 76 87 593 | 7 39 57 66 98 594 | 13 82 46 28 24 595 | 25 15 90 68 51 596 | 597 | 69 30 73 61 99 598 | 12 13 7 53 20 599 | 8 18 28 82 67 600 | 95 79 96 51 29 601 | 56 31 92 54 57 -------------------------------------------------------------------------------- /day5/input.txt: -------------------------------------------------------------------------------- 1 | 645,570 -> 517,570 2 | 100,409 -> 200,409 3 | 945,914 -> 98,67 4 | 22,934 -> 22,681 5 | 935,781 -> 524,370 6 | 750,304 -> 854,408 7 | 974,27 -> 26,975 8 | 529,58 -> 979,58 9 | 979,515 -> 550,944 10 | 925,119 -> 17,119 11 | 178,594 -> 45,461 12 | 252,366 -> 92,206 13 | 25,593 -> 250,593 14 | 956,34 -> 21,969 15 | 200,671 -> 200,369 16 | 628,614 -> 628,637 17 | 697,428 -> 237,428 18 | 554,40 -> 554,949 19 | 927,197 -> 469,197 20 | 504,779 -> 593,868 21 | 227,882 -> 227,982 22 | 56,905 -> 56,81 23 | 438,874 -> 566,746 24 | 989,73 -> 113,949 25 | 82,36 -> 616,570 26 | 670,423 -> 670,873 27 | 100,435 -> 291,435 28 | 242,81 -> 978,817 29 | 367,335 -> 367,332 30 | 890,584 -> 116,584 31 | 572,192 -> 572,561 32 | 391,516 -> 391,559 33 | 525,62 -> 525,540 34 | 787,540 -> 812,515 35 | 749,732 -> 423,406 36 | 745,911 -> 694,911 37 | 805,18 -> 972,18 38 | 701,565 -> 280,144 39 | 930,92 -> 129,893 40 | 15,989 -> 970,34 41 | 409,920 -> 409,345 42 | 192,743 -> 312,863 43 | 724,12 -> 29,707 44 | 323,664 -> 323,897 45 | 161,423 -> 391,653 46 | 59,363 -> 250,554 47 | 407,676 -> 19,288 48 | 449,585 -> 449,301 49 | 914,798 -> 914,806 50 | 917,401 -> 288,401 51 | 588,800 -> 647,800 52 | 897,883 -> 897,276 53 | 115,606 -> 41,532 54 | 692,482 -> 777,482 55 | 428,736 -> 69,736 56 | 405,44 -> 405,632 57 | 198,482 -> 198,620 58 | 988,816 -> 988,598 59 | 254,461 -> 186,393 60 | 560,783 -> 208,783 61 | 856,766 -> 215,125 62 | 182,30 -> 569,30 63 | 504,242 -> 656,242 64 | 393,929 -> 131,929 65 | 597,359 -> 26,930 66 | 502,690 -> 255,443 67 | 149,608 -> 149,748 68 | 293,662 -> 622,662 69 | 697,154 -> 697,228 70 | 587,804 -> 983,804 71 | 715,63 -> 715,709 72 | 496,831 -> 23,358 73 | 461,48 -> 68,441 74 | 927,565 -> 595,565 75 | 972,350 -> 689,350 76 | 728,438 -> 728,221 77 | 173,134 -> 173,804 78 | 720,368 -> 121,368 79 | 690,66 -> 201,66 80 | 218,680 -> 841,680 81 | 80,792 -> 80,467 82 | 624,319 -> 624,461 83 | 248,348 -> 532,64 84 | 357,260 -> 505,408 85 | 296,814 -> 13,531 86 | 819,216 -> 819,932 87 | 696,233 -> 696,840 88 | 219,93 -> 868,93 89 | 537,63 -> 905,63 90 | 777,940 -> 777,84 91 | 286,133 -> 286,735 92 | 969,967 -> 969,823 93 | 254,222 -> 859,827 94 | 426,728 -> 426,388 95 | 854,561 -> 854,363 96 | 755,861 -> 755,947 97 | 570,754 -> 439,754 98 | 333,351 -> 333,828 99 | 436,693 -> 436,262 100 | 982,987 -> 172,177 101 | 267,178 -> 267,270 102 | 218,201 -> 747,730 103 | 811,602 -> 829,584 104 | 602,659 -> 766,659 105 | 536,544 -> 483,597 106 | 280,881 -> 547,881 107 | 584,125 -> 129,125 108 | 386,210 -> 757,210 109 | 605,855 -> 605,668 110 | 19,985 -> 988,16 111 | 980,655 -> 836,655 112 | 73,189 -> 267,383 113 | 621,645 -> 533,645 114 | 36,12 -> 255,231 115 | 538,889 -> 130,481 116 | 921,217 -> 921,724 117 | 873,59 -> 873,311 118 | 76,918 -> 970,24 119 | 694,448 -> 694,983 120 | 573,891 -> 573,337 121 | 796,358 -> 403,358 122 | 532,928 -> 351,928 123 | 123,717 -> 123,446 124 | 874,714 -> 874,886 125 | 350,458 -> 728,458 126 | 798,140 -> 798,242 127 | 832,406 -> 864,406 128 | 188,55 -> 188,641 129 | 903,376 -> 509,376 130 | 50,954 -> 989,15 131 | 42,294 -> 25,294 132 | 544,273 -> 974,273 133 | 804,756 -> 103,55 134 | 398,184 -> 570,12 135 | 82,179 -> 902,179 136 | 461,728 -> 905,284 137 | 429,241 -> 26,241 138 | 128,715 -> 207,715 139 | 239,545 -> 934,545 140 | 978,769 -> 978,576 141 | 250,77 -> 515,77 142 | 521,533 -> 521,434 143 | 955,844 -> 314,203 144 | 144,601 -> 702,43 145 | 313,784 -> 339,784 146 | 388,692 -> 805,275 147 | 540,872 -> 540,72 148 | 971,19 -> 17,973 149 | 816,540 -> 386,540 150 | 933,246 -> 560,619 151 | 800,600 -> 387,187 152 | 272,791 -> 129,934 153 | 908,133 -> 110,931 154 | 759,191 -> 910,40 155 | 420,479 -> 749,150 156 | 604,946 -> 804,946 157 | 633,404 -> 771,266 158 | 948,974 -> 948,734 159 | 735,198 -> 105,828 160 | 889,653 -> 889,688 161 | 157,172 -> 822,837 162 | 206,670 -> 297,670 163 | 50,122 -> 792,864 164 | 656,664 -> 27,664 165 | 966,33 -> 523,33 166 | 985,40 -> 101,924 167 | 394,367 -> 574,547 168 | 440,573 -> 268,573 169 | 159,989 -> 159,130 170 | 867,123 -> 867,891 171 | 316,153 -> 316,249 172 | 680,59 -> 773,152 173 | 52,928 -> 52,182 174 | 128,595 -> 225,595 175 | 508,719 -> 591,719 176 | 595,447 -> 709,333 177 | 930,783 -> 283,136 178 | 366,236 -> 283,236 179 | 820,512 -> 381,951 180 | 135,450 -> 135,766 181 | 750,838 -> 534,838 182 | 259,304 -> 626,671 183 | 414,631 -> 916,129 184 | 193,862 -> 901,154 185 | 362,595 -> 362,209 186 | 377,215 -> 377,499 187 | 723,16 -> 577,16 188 | 335,238 -> 790,693 189 | 670,266 -> 871,65 190 | 288,313 -> 213,313 191 | 48,423 -> 592,967 192 | 960,323 -> 911,323 193 | 177,182 -> 177,235 194 | 773,918 -> 757,918 195 | 216,432 -> 147,432 196 | 808,500 -> 656,500 197 | 205,451 -> 776,451 198 | 598,985 -> 598,608 199 | 193,253 -> 241,205 200 | 912,384 -> 912,532 201 | 214,194 -> 214,738 202 | 508,356 -> 508,792 203 | 16,372 -> 30,372 204 | 384,854 -> 986,252 205 | 361,569 -> 851,569 206 | 923,550 -> 923,441 207 | 271,257 -> 318,304 208 | 651,345 -> 651,397 209 | 885,14 -> 929,14 210 | 199,547 -> 925,547 211 | 803,176 -> 104,875 212 | 840,302 -> 197,945 213 | 971,743 -> 355,127 214 | 684,951 -> 684,292 215 | 58,867 -> 58,953 216 | 351,187 -> 351,831 217 | 701,413 -> 701,728 218 | 482,159 -> 134,159 219 | 118,52 -> 950,884 220 | 115,968 -> 115,137 221 | 437,739 -> 627,929 222 | 653,153 -> 549,153 223 | 604,504 -> 560,460 224 | 538,865 -> 840,563 225 | 114,876 -> 114,124 226 | 152,899 -> 925,126 227 | 973,224 -> 973,387 228 | 492,360 -> 861,729 229 | 927,902 -> 108,83 230 | 754,678 -> 754,647 231 | 526,671 -> 423,671 232 | 675,608 -> 243,608 233 | 147,241 -> 147,242 234 | 456,770 -> 456,665 235 | 953,50 -> 102,901 236 | 415,869 -> 415,733 237 | 979,533 -> 169,533 238 | 336,385 -> 336,18 239 | 927,176 -> 927,587 240 | 370,317 -> 933,880 241 | 450,349 -> 450,103 242 | 755,235 -> 408,235 243 | 342,55 -> 931,55 244 | 417,707 -> 887,237 245 | 141,95 -> 131,85 246 | 776,209 -> 590,23 247 | 39,732 -> 469,302 248 | 743,602 -> 743,358 249 | 473,439 -> 473,545 250 | 270,290 -> 270,640 251 | 904,963 -> 949,963 252 | 71,91 -> 956,976 253 | 865,757 -> 276,757 254 | 59,72 -> 966,979 255 | 46,184 -> 788,926 256 | 360,833 -> 561,833 257 | 120,452 -> 528,452 258 | 704,927 -> 158,381 259 | 140,481 -> 140,350 260 | 929,920 -> 929,342 261 | 328,381 -> 328,866 262 | 897,389 -> 227,389 263 | 341,614 -> 29,614 264 | 609,327 -> 609,582 265 | 727,858 -> 727,941 266 | 349,536 -> 349,500 267 | 280,959 -> 259,959 268 | 973,637 -> 832,637 269 | 161,255 -> 979,255 270 | 512,826 -> 149,826 271 | 308,769 -> 22,769 272 | 60,692 -> 60,262 273 | 787,31 -> 753,31 274 | 932,166 -> 932,127 275 | 514,77 -> 514,646 276 | 535,434 -> 535,979 277 | 838,799 -> 838,332 278 | 565,956 -> 565,477 279 | 74,195 -> 274,195 280 | 916,715 -> 907,715 281 | 721,655 -> 721,542 282 | 180,784 -> 928,784 283 | 16,128 -> 313,128 284 | 23,330 -> 23,704 285 | 530,723 -> 530,88 286 | 869,272 -> 765,376 287 | 878,185 -> 353,185 288 | 72,800 -> 514,800 289 | 319,117 -> 307,117 290 | 436,405 -> 496,345 291 | 327,459 -> 641,145 292 | 358,309 -> 661,612 293 | 60,225 -> 811,976 294 | 113,130 -> 794,130 295 | 559,950 -> 32,423 296 | 626,110 -> 626,319 297 | 50,39 -> 989,978 298 | 257,627 -> 799,627 299 | 581,843 -> 581,493 300 | 869,18 -> 208,18 301 | 184,395 -> 184,263 302 | 454,888 -> 165,599 303 | 637,920 -> 637,544 304 | 170,982 -> 273,982 305 | 98,354 -> 668,924 306 | 32,409 -> 32,925 307 | 154,175 -> 273,294 308 | 425,896 -> 870,451 309 | 198,319 -> 615,736 310 | 170,582 -> 170,712 311 | 141,645 -> 141,639 312 | 482,768 -> 486,768 313 | 940,969 -> 24,53 314 | 680,360 -> 959,360 315 | 315,905 -> 315,96 316 | 22,666 -> 22,247 317 | 722,40 -> 722,714 318 | 585,31 -> 585,21 319 | 479,254 -> 307,254 320 | 291,182 -> 291,855 321 | 684,698 -> 402,698 322 | 20,984 -> 988,16 323 | 256,424 -> 17,663 324 | 825,380 -> 820,385 325 | 254,622 -> 254,315 326 | 98,855 -> 98,694 327 | 220,719 -> 220,117 328 | 615,653 -> 656,694 329 | 427,12 -> 427,745 330 | 20,64 -> 828,872 331 | 739,203 -> 434,203 332 | 546,576 -> 130,160 333 | 730,835 -> 299,835 334 | 927,512 -> 927,586 335 | 411,192 -> 868,192 336 | 917,630 -> 678,630 337 | 620,588 -> 620,26 338 | 786,488 -> 486,488 339 | 746,640 -> 251,145 340 | 585,556 -> 585,119 341 | 977,202 -> 762,202 342 | 587,244 -> 587,877 343 | 693,479 -> 693,859 344 | 59,816 -> 59,475 345 | 191,941 -> 878,254 346 | 150,920 -> 926,144 347 | 856,397 -> 856,739 348 | 380,965 -> 549,796 349 | 637,323 -> 909,595 350 | 848,219 -> 304,763 351 | 123,146 -> 589,146 352 | 546,122 -> 651,122 353 | 131,711 -> 814,28 354 | 727,274 -> 296,274 355 | 101,546 -> 479,168 356 | 508,517 -> 615,410 357 | 492,115 -> 492,250 358 | 212,65 -> 770,623 359 | 118,938 -> 857,199 360 | 623,843 -> 98,843 361 | 86,153 -> 701,768 362 | 81,98 -> 81,604 363 | 173,313 -> 173,533 364 | 792,396 -> 792,242 365 | 975,985 -> 10,20 366 | 762,661 -> 726,661 367 | 216,327 -> 216,122 368 | 446,658 -> 98,658 369 | 85,184 -> 314,184 370 | 165,750 -> 313,750 371 | 729,583 -> 729,640 372 | 382,36 -> 382,326 373 | 487,32 -> 225,32 374 | 389,722 -> 582,915 375 | 954,965 -> 86,965 376 | 747,376 -> 747,96 377 | 254,259 -> 254,482 378 | 149,256 -> 149,871 379 | 893,207 -> 708,22 380 | 195,907 -> 195,82 381 | 342,686 -> 457,571 382 | 647,469 -> 468,469 383 | 150,525 -> 832,525 384 | 90,907 -> 90,31 385 | 389,554 -> 389,318 386 | 138,327 -> 138,310 387 | 861,126 -> 861,549 388 | 355,583 -> 355,534 389 | 591,182 -> 181,592 390 | 73,84 -> 897,908 391 | 326,989 -> 425,989 392 | 835,688 -> 724,799 393 | 844,493 -> 844,974 394 | 172,436 -> 172,12 395 | 536,933 -> 48,445 396 | 192,531 -> 287,531 397 | 286,547 -> 80,547 398 | 929,795 -> 697,795 399 | 790,681 -> 433,681 400 | 692,229 -> 731,229 401 | 377,667 -> 14,304 402 | 535,226 -> 116,645 403 | 338,861 -> 338,343 404 | 668,160 -> 853,160 405 | 188,157 -> 667,636 406 | 62,934 -> 951,45 407 | 948,820 -> 978,820 408 | 860,884 -> 157,884 409 | 794,251 -> 783,251 410 | 317,381 -> 591,655 411 | 459,876 -> 459,307 412 | 146,822 -> 903,65 413 | 374,739 -> 891,739 414 | 619,575 -> 973,929 415 | 544,351 -> 544,124 416 | 300,335 -> 818,335 417 | 158,220 -> 418,480 418 | 107,953 -> 988,953 419 | 304,753 -> 543,753 420 | 948,95 -> 140,903 421 | 832,451 -> 526,145 422 | 966,34 -> 402,598 423 | 72,123 -> 716,123 424 | 336,294 -> 84,294 425 | 116,605 -> 116,889 426 | 700,742 -> 700,217 427 | 551,554 -> 973,554 428 | 684,181 -> 66,799 429 | 86,949 -> 86,173 430 | 834,361 -> 834,942 431 | 508,668 -> 627,549 432 | 213,695 -> 704,695 433 | 260,979 -> 868,371 434 | 825,435 -> 825,67 435 | 956,854 -> 66,854 436 | 390,444 -> 697,444 437 | 360,450 -> 720,810 438 | 153,514 -> 794,514 439 | 253,261 -> 253,298 440 | 925,679 -> 925,499 441 | 391,282 -> 441,282 442 | 86,366 -> 779,366 443 | 687,312 -> 687,629 444 | 304,172 -> 732,600 445 | 571,518 -> 263,518 446 | 814,252 -> 118,252 447 | 108,920 -> 108,162 448 | 154,965 -> 928,191 449 | 635,875 -> 635,947 450 | 986,31 -> 47,970 451 | 746,35 -> 746,636 452 | 735,849 -> 334,448 453 | 826,510 -> 906,590 454 | 834,745 -> 834,949 455 | 843,401 -> 564,122 456 | 179,212 -> 179,32 457 | 354,906 -> 233,906 458 | 593,439 -> 196,42 459 | 707,446 -> 242,446 460 | 511,84 -> 511,406 461 | 109,299 -> 100,290 462 | 410,79 -> 410,784 463 | 806,923 -> 54,171 464 | 592,83 -> 592,189 465 | 413,28 -> 413,469 466 | 17,844 -> 17,691 467 | 130,419 -> 205,344 468 | 374,247 -> 849,247 469 | 650,344 -> 653,344 470 | 563,942 -> 563,726 471 | 771,966 -> 450,966 472 | 499,693 -> 788,693 473 | 962,458 -> 962,356 474 | 28,683 -> 765,683 475 | 432,546 -> 432,708 476 | 519,974 -> 176,974 477 | 797,744 -> 280,227 478 | 505,228 -> 547,228 479 | 401,366 -> 401,754 480 | 356,470 -> 123,470 481 | 57,909 -> 229,909 482 | 343,880 -> 539,880 483 | 221,851 -> 221,297 484 | 520,677 -> 894,677 485 | 216,805 -> 688,805 486 | 158,901 -> 847,901 487 | 98,129 -> 98,969 488 | 793,203 -> 210,786 489 | 852,855 -> 135,138 490 | 944,90 -> 103,931 491 | 691,768 -> 583,768 492 | 784,617 -> 637,764 493 | 222,160 -> 819,757 494 | 145,982 -> 145,216 495 | 837,355 -> 99,355 496 | 324,121 -> 324,14 497 | 773,851 -> 773,413 498 | 778,550 -> 686,458 499 | 81,56 -> 338,313 500 | 356,512 -> 356,441 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /day19/main.go: -------------------------------------------------------------------------------- 1 | package day19 2 | 3 | import ( 4 | "math" 5 | 6 | "github.com/bwplotka/efficiency-advent-2021/day6" 7 | "github.com/go-gl/mathgl/mgl64" 8 | "github.com/pkg/errors" 9 | ) 10 | 11 | type vec3 struct { 12 | x, y, z int64 13 | } 14 | 15 | type beacon struct { 16 | mgl64.Vec3 17 | 18 | // Manhattan distances to others within the scanner beacon is in. 19 | neighbours map[int64]int 20 | } 21 | 22 | func abs(x float64) int64 { 23 | if x < 0 { 24 | return int64(-1 * x) 25 | } 26 | return int64(x) 27 | } 28 | 29 | func fillNeighbours(beacons []beacon) { 30 | for j := 0; j < len(beacons)-1; j++ { 31 | for k := j + 1; k < len(beacons); k++ { 32 | dist := beacons[j].manhattanDist(&beacons[k]) 33 | beacons[j].neighbours[dist]++ 34 | beacons[k].neighbours[dist]++ 35 | } 36 | } 37 | } 38 | 39 | func manhattanDist(a, b mgl64.Vec3) int64 { 40 | return abs(a.X()-b.X()) + abs(a.Y()-b.Y()) + abs(a.Z()-b.Z()) 41 | } 42 | 43 | func (b *beacon) manhattanDist(o *beacon) int64 { 44 | return manhattanDist(b.Vec3, o.Vec3) 45 | } 46 | 47 | func (b *beacon) isPossiblySame(o *beacon, overlapThreshold int) bool { 48 | var overlaps int 49 | for n := range b.neighbours { 50 | overlaps += o.neighbours[n] 51 | if overlaps >= (overlapThreshold - 1) { // -1 because of the `b` is accounted already. 52 | return true 53 | } 54 | } 55 | return false 56 | } 57 | 58 | func parse(input string) ([][]beacon, error) { 59 | var ( 60 | currScanner = -1 61 | scannerBeacons [][]beacon 62 | ) 63 | for i := 0; i < len(input); { 64 | if input[i] == '\n' { 65 | i++ 66 | continue 67 | } 68 | 69 | if input[i] == '-' && input[i+1] == '-' { 70 | currScanner++ 71 | scannerBeacons = append(scannerBeacons, nil) 72 | for input[i] != '\n' { 73 | i++ 74 | } 75 | i++ 76 | continue 77 | } 78 | 79 | j := i 80 | for ; input[i] == '-' || (input[i] >= '0' && input[i] <= '9'); i++ { 81 | } 82 | 83 | x, err := day6.ParseInt(input[j:i]) 84 | if err != nil { 85 | return nil, err 86 | } 87 | i++ 88 | 89 | j = i 90 | for ; input[i] == '-' || (input[i] >= '0' && input[i] <= '9'); i++ { 91 | } 92 | 93 | y, err := day6.ParseInt(input[j:i]) 94 | if err != nil { 95 | return nil, err 96 | } 97 | i++ 98 | 99 | j = i 100 | for ; input[i] == '-' || (input[i] >= '0' && input[i] <= '9'); i++ { 101 | } 102 | 103 | z, err := day6.ParseInt(input[j:i]) 104 | if err != nil { 105 | return nil, err 106 | } 107 | i++ 108 | 109 | b := beacon{Vec3: mgl64.Vec3{float64(x), float64(y), float64(z)}, neighbours: map[int64]int{}} 110 | scannerBeacons[currScanner] = append(scannerBeacons[currScanner], b) 111 | } 112 | return scannerBeacons, nil 113 | } 114 | 115 | type transform struct { 116 | rotation mgl64.Mat3 117 | move mgl64.Vec3 118 | } 119 | 120 | func (t *transform) transformInPlace(bs []beacon) { 121 | for i := range bs { 122 | bs[i].Vec3 = round(t.rotation.Mul3x1(bs[i].Vec3)).Add(t.move) 123 | } 124 | } 125 | func (t *transform) transformVec3(pos mgl64.Vec3) mgl64.Vec3 { 126 | return round(t.rotation.Mul3x1(pos)).Add(t.move) 127 | } 128 | 129 | func round(v mgl64.Vec3) mgl64.Vec3 { 130 | v[0] = mgl64.Round(v.X(), 0) 131 | v[1] = mgl64.Round(v.Y(), 0) 132 | v[2] = mgl64.Round(v.Z(), 0) 133 | return v 134 | } 135 | 136 | func findTransform(scanA, scanB []beacon, overlapThreshold int) (t *transform, overlap bool) { 137 | // Check if there are at least overlapThreshold pair of "same" beacons. 138 | // Gather four of those pairs, since we need to solve 4 vars equation to find rot and translation. 139 | // NOTE: Those four cannot have the same normalized vector (same function). Otherwise our equation won't be solvable. 140 | //which in normalized are not the same formFind four the same pair beacons from each overlapping scanners (if any). 141 | var ( 142 | bsScanA [4]mgl64.Vec3 143 | bsScanB [4]mgl64.Vec3 144 | 145 | i = -1 146 | normalized1 = map[struct{ x, y, z float64 }]struct{}{} 147 | normalized2 = map[struct{ x, y, z float64 }]struct{}{} 148 | ) 149 | 150 | outer: 151 | for sAb := range scanA { 152 | for sBb := range scanB { 153 | 154 | bA := &(scanA[sAb]) 155 | bB := &(scanB[sBb]) 156 | 157 | if !bA.isPossiblySame(bB, overlapThreshold) { 158 | continue 159 | } 160 | 161 | // We can't use pair of points for matching that when normalized is exactly the same as another pair. 162 | x, y, z := round(bA.Normalize()).Elem() 163 | k := struct{ x, y, z float64 }{x, y, z} 164 | _, ok1 := normalized1[k] 165 | 166 | x, y, z = round(bB.Normalize()).Elem() 167 | k2 := struct{ x, y, z float64 }{x, y, z} 168 | _, ok2 := normalized2[k2] 169 | if ok1 && ok2 { 170 | continue 171 | } 172 | 173 | normalized1[k2] = struct{}{} 174 | normalized2[k2] = struct{}{} 175 | 176 | i++ 177 | bsScanA[i] = bA.Vec3 178 | bsScanB[i] = bB.Vec3 179 | if i >= 3 { 180 | break outer 181 | } 182 | } 183 | } 184 | if i < 3 { 185 | return nil, false 186 | } 187 | 188 | // We need to find what rotation and offset has to be applied to transform scan B points to scan A coordinates.. 189 | // Useful docs: 190 | // * https://towardsdatascience.com/essential-math-for-data-science-basis-and-change-of-basis-f7af2348d463 191 | // * https://medium.com/@vasanth260m12/solving-linear-regression-using-linear-algebra-in-golang-b0d66b7056ff 192 | // 193 | // Overall we need to find change basis + translation, so. We can do it since we now translation looks like this: 194 | // 195 | // [v]A = CB * [b]B + [off], where CB is change basis matrix 3x3 and off is offset vector. 196 | // 197 | // Now we "just" need to solve three times four equations with four variables to find CB and off. 198 | // 199 | // bsScanA[0].X = x1*bsScanB[0].X + y1*bsScanB[0].Y + z1*bsScanB[0].Z + c1 200 | // bsScanA[1].X = x1*bsScanB[1].X + y1*bsScanB[1].Y + z1*bsScanB[1].Z + c1 201 | // bsScanA[2].X = x1*bsScanB[2].X + y1*bsScanB[2].Y + z1*bsScanB[2].Z + c1 202 | // bsScanA[3].X = x1*bsScanB[3].X + y1*bsScanB[3].Y + z1*bsScanB[3].Z + c1 203 | // .. and the same for x2, x3, y2, c2 and y3, z2, z3, c3 (: 204 | 205 | // NOTE: Within our task we can assume all x, y and z can only be integers -1, 0 or 1, still this algo should work for other cases too. 206 | 207 | invCoefficients := mgl64.Mat4{ 208 | bsScanB[0].X(), bsScanB[1].X(), bsScanB[2].X(), bsScanB[3].X(), // Col 0. 209 | bsScanB[0].Y(), bsScanB[1].Y(), bsScanB[2].Y(), bsScanB[3].Y(), 210 | bsScanB[0].Z(), bsScanB[1].Z(), bsScanB[2].Z(), bsScanB[3].Z(), 211 | 1, 1, 1, 1, 212 | }.Inv() 213 | 214 | xyzc1 := invCoefficients.Mul4x1(mgl64.Vec4{ 215 | bsScanA[0].X(), 216 | bsScanA[1].X(), 217 | bsScanA[2].X(), 218 | bsScanA[3].X(), 219 | }) 220 | 221 | xyzc2 := invCoefficients.Mul4x1(mgl64.Vec4{ 222 | bsScanA[0].Y(), 223 | bsScanA[1].Y(), 224 | bsScanA[2].Y(), 225 | bsScanA[3].Y(), 226 | }) 227 | 228 | xyzc3 := invCoefficients.Mul4x1(mgl64.Vec4{ 229 | bsScanA[0].Z(), 230 | bsScanA[1].Z(), 231 | bsScanA[2].Z(), 232 | bsScanA[3].Z(), 233 | }) 234 | 235 | tr := &transform{ 236 | // Inverse of change CB will get us from scanner B to A. 237 | rotation: mgl64.Mat3FromCols(xyzc1.Vec3(), xyzc2.Vec3(), xyzc3.Vec3()).Inv(), 238 | move: round(mgl64.Vec3{xyzc1.W(), xyzc2.W(), xyzc3.W()}), 239 | } 240 | 241 | return tr, true 242 | } 243 | 244 | func HowManyBeaconsPart1(input string, overlapThreshold int) (_ int, err error) { 245 | scannerBeacons, err := parse(input) 246 | if err != nil { 247 | return 0, err 248 | } 249 | 250 | transforms := make([][]*transform, len(scannerBeacons)) 251 | to0transforms := make([]bool, len(scannerBeacons)) 252 | for i := 0; i < len(scannerBeacons); i++ { 253 | fillNeighbours(scannerBeacons[i]) 254 | transforms[i] = make([]*transform, len(scannerBeacons)) 255 | } 256 | 257 | // Find all transforms and hope that all in chained way overlap to 0 :crossed_fingers: 258 | // TODO(bwplotka): We could optimize by checking only half and then inverting vice versa transformation. 259 | for j := 0; j < len(scannerBeacons); j++ { 260 | for k := 0; k < len(scannerBeacons); k++ { 261 | if j == k { 262 | continue 263 | } 264 | 265 | tr, ok := findTransform(scannerBeacons[j], scannerBeacons[k], overlapThreshold) 266 | if !ok { 267 | continue 268 | } 269 | transforms[j][k] = tr 270 | to0transforms[k] = true // Potentially true, we will double-check later. 271 | } 272 | } 273 | 274 | // Assume 0 overlaps with others in direct or indirect way. 275 | allBeacons := map[vec3]struct{}{} 276 | for _, sXb := range scannerBeacons[0] { 277 | allBeacons[vec3{int64(sXb.X()), int64(sXb.Y()), int64(sXb.Z())}] = struct{}{} 278 | } 279 | 280 | cacheTransformStepsFromTo0 := make([][]int, len(transforms)) 281 | for j := 1; j < len(scannerBeacons); j++ { 282 | if err := findTransformStepsTo0(transforms, j, to0transforms, cacheTransformStepsFromTo0); err != nil { 283 | return 0, err 284 | } 285 | 286 | prev := j 287 | for _, step := range cacheTransformStepsFromTo0[j] { 288 | transforms[step][prev].transformInPlace(scannerBeacons[j]) 289 | prev = step 290 | } 291 | for _, sXb := range scannerBeacons[j] { 292 | allBeacons[vec3{int64(sXb.X()), int64(sXb.Y()), int64(sXb.Z())}] = struct{}{} 293 | } 294 | } 295 | return len(allBeacons), nil 296 | } 297 | 298 | type stack struct { 299 | s []int 300 | } 301 | 302 | func (s *stack) pop() int { 303 | i := s.s[len(s.s)-1] 304 | s.s = s.s[:len(s.s)-1] 305 | return i 306 | } 307 | 308 | func (s *stack) push(v int) { 309 | s.s = append(s.s, v) 310 | } 311 | 312 | func (s *stack) len() int { 313 | return len(s.s) 314 | } 315 | 316 | // TODO(bwplotka): Probably too complex, but it's 3am... 317 | func findTransformStepsTo0(transforms [][]*transform, from int, to0transforms []bool, cacheSteps [][]int) error { 318 | if len(cacheSteps[from]) > 0 { 319 | return nil 320 | } 321 | 322 | // Use stack for DFS. 323 | var steps stack 324 | steps.push(from) 325 | 326 | defer func() { 327 | // On way back, always unwind cache steps and fill intermediate steps. 328 | // This allows us to hit cache before we hit preset to0transforms = false for that item. 329 | for i, step := range cacheSteps[from] { 330 | if len(cacheSteps[step]) > 0 && len(cacheSteps[step]) < len(cacheSteps[from][i+1:]) { 331 | continue 332 | } 333 | cacheSteps[step] = cacheSteps[from][i+1:] 334 | } 335 | 336 | }() 337 | 338 | stackLoop: 339 | for steps.len() > 0 { 340 | currFrom := steps.s[steps.len()-1] 341 | for i, potentialTo := range transforms { 342 | if transforms[0][currFrom] != nil { 343 | // Got it, cache and return. 344 | cacheSteps[from] = append(cacheSteps[from], append(steps.s[1:], 0)...) 345 | return nil 346 | } 347 | 348 | if potentialTo[currFrom] == nil { 349 | continue 350 | } 351 | 352 | if len(cacheSteps[i]) > 0 { 353 | cacheSteps[from] = append(cacheSteps[from], append(append(steps.s[1:], i), cacheSteps[i]...)...) 354 | return nil 355 | } 356 | 357 | if !to0transforms[i] { 358 | // We learned previously, that this path is not chainable to 0. 359 | continue 360 | } 361 | 362 | to0transforms[currFrom] = false 363 | steps.push(i) 364 | continue stackLoop 365 | } 366 | 367 | // No chain from here, go back to parent. 368 | to0transforms[steps.pop()] = false 369 | } 370 | return errors.New("no chain, we cannot transform") 371 | } 372 | 373 | func ManhattanDistPart2(input string, overlapThreshold int) (_ int, err error) { 374 | scannerBeacons, err := parse(input) 375 | if err != nil { 376 | return 0, err 377 | } 378 | 379 | transforms := make([][]*transform, len(scannerBeacons)) 380 | to0transforms := make([]bool, len(scannerBeacons)) 381 | for i := 0; i < len(scannerBeacons); i++ { 382 | fillNeighbours(scannerBeacons[i]) 383 | transforms[i] = make([]*transform, len(scannerBeacons)) 384 | } 385 | 386 | // Find all transforms and hope that all in chained way overlap to 0 :crossed_fingers: 387 | // TODO(bwplotka): We could optimize by checking only half and then inverting vice versa transformation. 388 | for j := 0; j < len(scannerBeacons); j++ { 389 | for k := 0; k < len(scannerBeacons); k++ { 390 | if j == k { 391 | continue 392 | } 393 | tr, ok := findTransform(scannerBeacons[j], scannerBeacons[k], overlapThreshold) 394 | if !ok { 395 | continue 396 | } 397 | transforms[j][k] = tr 398 | to0transforms[k] = true // Potentially true, we will double-check later. 399 | } 400 | } 401 | 402 | cacheTransformStepsFromTo0 := make([][]int, len(transforms)) 403 | 404 | scannerPositions := make([]mgl64.Vec3, len(scannerBeacons)) 405 | for j := 1; j < len(scannerPositions); j++ { 406 | if err := findTransformStepsTo0(transforms, j, to0transforms, cacheTransformStepsFromTo0); err != nil { 407 | return 0, err 408 | } 409 | 410 | prev := j 411 | for _, step := range cacheTransformStepsFromTo0[j] { 412 | scannerPositions[j] = transforms[step][prev].transformVec3(scannerPositions[j]) 413 | prev = step 414 | } 415 | } 416 | 417 | max := math.MinInt64 418 | for i := 0; i < len(scannerPositions); i++ { 419 | for j := 0; j < len(scannerPositions); j++ { 420 | if j == i { 421 | continue 422 | } 423 | 424 | d := int(manhattanDist(scannerPositions[i], scannerPositions[j])) 425 | if d > max { 426 | max = d 427 | } 428 | } 429 | } 430 | return max, nil 431 | } 432 | -------------------------------------------------------------------------------- /day2/input.txt: -------------------------------------------------------------------------------- 1 | forward 3 2 | down 9 3 | forward 5 4 | up 1 5 | forward 2 6 | down 1 7 | down 7 8 | down 5 9 | up 6 10 | forward 3 11 | down 6 12 | forward 9 13 | down 6 14 | forward 2 15 | down 4 16 | forward 4 17 | down 9 18 | down 7 19 | down 2 20 | down 4 21 | forward 3 22 | forward 6 23 | down 3 24 | up 1 25 | down 5 26 | down 8 27 | down 1 28 | forward 9 29 | forward 4 30 | forward 3 31 | down 3 32 | down 6 33 | down 3 34 | up 2 35 | down 3 36 | down 9 37 | down 1 38 | down 9 39 | up 8 40 | down 1 41 | down 9 42 | forward 9 43 | forward 2 44 | down 1 45 | forward 2 46 | down 9 47 | forward 9 48 | up 7 49 | forward 1 50 | up 8 51 | forward 7 52 | forward 6 53 | forward 2 54 | down 8 55 | forward 7 56 | down 3 57 | down 2 58 | down 1 59 | forward 2 60 | down 6 61 | forward 8 62 | down 7 63 | forward 9 64 | down 7 65 | down 9 66 | forward 2 67 | forward 2 68 | up 3 69 | down 4 70 | down 8 71 | forward 5 72 | down 4 73 | down 8 74 | down 2 75 | up 7 76 | down 7 77 | up 9 78 | up 9 79 | up 1 80 | forward 2 81 | up 4 82 | forward 5 83 | forward 9 84 | forward 9 85 | forward 3 86 | down 6 87 | up 3 88 | down 1 89 | forward 8 90 | forward 2 91 | down 7 92 | forward 9 93 | forward 1 94 | forward 8 95 | forward 8 96 | down 2 97 | down 6 98 | forward 8 99 | forward 8 100 | forward 3 101 | forward 4 102 | down 3 103 | up 3 104 | forward 1 105 | forward 4 106 | down 1 107 | down 4 108 | down 2 109 | down 3 110 | forward 5 111 | down 3 112 | up 5 113 | forward 9 114 | down 8 115 | up 6 116 | down 6 117 | up 7 118 | up 7 119 | forward 1 120 | forward 7 121 | down 1 122 | up 3 123 | down 1 124 | forward 7 125 | forward 1 126 | forward 9 127 | down 2 128 | forward 9 129 | down 3 130 | down 5 131 | forward 2 132 | up 3 133 | forward 5 134 | forward 5 135 | down 8 136 | down 7 137 | forward 6 138 | down 2 139 | down 5 140 | up 4 141 | up 5 142 | down 6 143 | forward 5 144 | down 3 145 | down 8 146 | forward 7 147 | down 5 148 | down 5 149 | down 9 150 | down 9 151 | down 2 152 | down 7 153 | up 4 154 | forward 8 155 | up 6 156 | down 5 157 | forward 1 158 | up 2 159 | down 6 160 | up 8 161 | up 7 162 | down 6 163 | forward 4 164 | down 6 165 | up 6 166 | up 4 167 | forward 5 168 | forward 4 169 | forward 6 170 | down 3 171 | down 7 172 | down 9 173 | forward 2 174 | forward 6 175 | down 3 176 | forward 1 177 | forward 2 178 | forward 9 179 | up 5 180 | down 7 181 | down 6 182 | forward 2 183 | forward 1 184 | up 3 185 | down 8 186 | forward 9 187 | down 7 188 | forward 7 189 | up 2 190 | up 8 191 | up 8 192 | forward 7 193 | forward 5 194 | forward 9 195 | down 7 196 | down 7 197 | forward 5 198 | forward 4 199 | forward 2 200 | forward 8 201 | up 3 202 | up 7 203 | forward 8 204 | forward 6 205 | forward 2 206 | forward 6 207 | up 3 208 | up 1 209 | forward 6 210 | forward 9 211 | down 1 212 | forward 6 213 | forward 4 214 | up 6 215 | forward 1 216 | down 7 217 | forward 7 218 | up 5 219 | down 5 220 | down 3 221 | forward 4 222 | forward 6 223 | up 6 224 | forward 9 225 | forward 2 226 | down 7 227 | forward 9 228 | down 9 229 | forward 2 230 | up 1 231 | down 4 232 | forward 6 233 | forward 4 234 | down 6 235 | forward 1 236 | up 3 237 | up 5 238 | down 8 239 | forward 2 240 | up 7 241 | down 5 242 | down 2 243 | down 6 244 | forward 7 245 | down 8 246 | up 8 247 | down 7 248 | down 9 249 | down 7 250 | down 8 251 | down 4 252 | up 3 253 | up 9 254 | down 4 255 | forward 7 256 | down 5 257 | up 8 258 | down 3 259 | forward 8 260 | down 3 261 | down 4 262 | down 1 263 | forward 5 264 | down 4 265 | down 8 266 | up 7 267 | forward 2 268 | forward 8 269 | down 1 270 | down 3 271 | forward 4 272 | forward 5 273 | forward 8 274 | forward 1 275 | down 1 276 | down 9 277 | up 8 278 | forward 6 279 | down 8 280 | down 2 281 | forward 9 282 | down 5 283 | down 8 284 | up 8 285 | up 5 286 | forward 9 287 | up 6 288 | down 9 289 | up 1 290 | down 2 291 | down 4 292 | forward 9 293 | forward 1 294 | up 2 295 | down 7 296 | forward 9 297 | down 9 298 | down 6 299 | down 9 300 | down 8 301 | forward 7 302 | forward 6 303 | forward 9 304 | forward 9 305 | forward 8 306 | forward 5 307 | up 2 308 | forward 9 309 | forward 2 310 | down 1 311 | down 1 312 | down 5 313 | down 1 314 | down 7 315 | up 2 316 | up 7 317 | forward 7 318 | forward 8 319 | down 2 320 | down 2 321 | down 3 322 | up 8 323 | up 8 324 | up 3 325 | forward 3 326 | down 7 327 | up 4 328 | up 8 329 | down 5 330 | forward 4 331 | forward 7 332 | down 9 333 | up 7 334 | forward 8 335 | forward 5 336 | forward 8 337 | forward 8 338 | forward 6 339 | forward 5 340 | forward 2 341 | down 3 342 | up 2 343 | forward 6 344 | forward 5 345 | down 9 346 | down 2 347 | down 7 348 | down 2 349 | forward 2 350 | forward 6 351 | forward 8 352 | down 7 353 | forward 4 354 | down 3 355 | down 5 356 | forward 1 357 | down 9 358 | forward 5 359 | down 4 360 | forward 9 361 | down 5 362 | down 4 363 | down 4 364 | down 7 365 | forward 9 366 | down 3 367 | down 5 368 | down 6 369 | down 4 370 | forward 4 371 | down 4 372 | up 1 373 | down 4 374 | up 7 375 | forward 4 376 | forward 5 377 | up 9 378 | down 4 379 | up 9 380 | forward 9 381 | down 8 382 | down 1 383 | up 7 384 | down 4 385 | up 4 386 | forward 9 387 | down 9 388 | down 4 389 | up 4 390 | down 5 391 | forward 2 392 | up 4 393 | down 3 394 | forward 9 395 | forward 8 396 | down 2 397 | forward 5 398 | up 5 399 | down 9 400 | down 7 401 | down 5 402 | down 9 403 | down 1 404 | down 7 405 | down 2 406 | forward 4 407 | up 7 408 | forward 7 409 | down 8 410 | down 2 411 | down 8 412 | up 6 413 | down 7 414 | down 7 415 | forward 3 416 | up 3 417 | forward 6 418 | down 8 419 | down 3 420 | up 2 421 | down 9 422 | forward 3 423 | down 9 424 | down 6 425 | up 8 426 | forward 5 427 | down 9 428 | up 2 429 | up 8 430 | down 8 431 | up 1 432 | up 2 433 | forward 5 434 | up 3 435 | down 7 436 | forward 4 437 | forward 2 438 | up 1 439 | forward 2 440 | up 1 441 | down 1 442 | down 5 443 | forward 6 444 | up 2 445 | down 7 446 | down 8 447 | down 9 448 | up 9 449 | down 2 450 | up 2 451 | forward 9 452 | forward 6 453 | forward 5 454 | down 6 455 | up 6 456 | forward 6 457 | forward 3 458 | down 3 459 | forward 2 460 | forward 4 461 | forward 1 462 | down 9 463 | forward 3 464 | forward 2 465 | down 5 466 | up 2 467 | forward 7 468 | down 4 469 | forward 5 470 | down 4 471 | forward 2 472 | down 4 473 | up 3 474 | forward 6 475 | forward 9 476 | down 1 477 | forward 2 478 | up 8 479 | forward 4 480 | up 9 481 | up 4 482 | up 3 483 | forward 5 484 | down 7 485 | forward 2 486 | up 4 487 | forward 7 488 | down 8 489 | forward 6 490 | forward 4 491 | up 5 492 | down 4 493 | down 6 494 | down 3 495 | forward 6 496 | down 9 497 | up 6 498 | forward 3 499 | down 4 500 | forward 8 501 | forward 1 502 | down 3 503 | down 4 504 | up 4 505 | forward 1 506 | up 5 507 | up 9 508 | forward 4 509 | up 9 510 | forward 2 511 | up 5 512 | up 5 513 | up 7 514 | up 4 515 | down 3 516 | forward 8 517 | forward 1 518 | up 1 519 | down 8 520 | up 3 521 | up 4 522 | up 2 523 | up 8 524 | up 7 525 | down 8 526 | up 8 527 | forward 9 528 | down 8 529 | up 5 530 | forward 6 531 | forward 4 532 | down 8 533 | down 9 534 | down 4 535 | down 6 536 | forward 4 537 | up 6 538 | up 1 539 | forward 7 540 | up 4 541 | down 6 542 | up 3 543 | down 4 544 | forward 8 545 | forward 4 546 | up 2 547 | down 3 548 | up 3 549 | up 9 550 | down 4 551 | forward 4 552 | forward 5 553 | forward 2 554 | down 1 555 | down 6 556 | down 1 557 | forward 6 558 | down 2 559 | forward 1 560 | down 2 561 | down 4 562 | forward 1 563 | down 8 564 | up 2 565 | down 5 566 | forward 9 567 | forward 4 568 | down 9 569 | forward 8 570 | forward 2 571 | forward 7 572 | forward 1 573 | forward 1 574 | down 8 575 | forward 2 576 | forward 8 577 | forward 7 578 | forward 9 579 | down 4 580 | down 2 581 | forward 1 582 | forward 2 583 | down 1 584 | forward 1 585 | forward 5 586 | down 1 587 | down 5 588 | down 1 589 | forward 2 590 | up 9 591 | forward 2 592 | forward 4 593 | down 9 594 | up 7 595 | down 1 596 | up 4 597 | forward 9 598 | up 6 599 | up 8 600 | down 3 601 | forward 9 602 | up 6 603 | down 1 604 | forward 9 605 | forward 3 606 | up 5 607 | forward 9 608 | down 1 609 | forward 5 610 | up 5 611 | down 1 612 | up 4 613 | forward 3 614 | forward 1 615 | up 4 616 | forward 3 617 | forward 9 618 | down 2 619 | forward 5 620 | forward 4 621 | forward 9 622 | down 5 623 | forward 8 624 | forward 1 625 | down 3 626 | down 2 627 | down 3 628 | up 8 629 | forward 3 630 | forward 6 631 | up 8 632 | down 6 633 | forward 8 634 | forward 1 635 | down 8 636 | down 7 637 | forward 8 638 | down 2 639 | forward 8 640 | down 4 641 | forward 1 642 | down 1 643 | up 6 644 | forward 1 645 | up 7 646 | down 2 647 | forward 5 648 | up 9 649 | down 5 650 | forward 4 651 | down 6 652 | down 9 653 | forward 8 654 | up 2 655 | up 7 656 | forward 2 657 | forward 5 658 | up 9 659 | down 4 660 | forward 9 661 | down 4 662 | down 3 663 | down 6 664 | down 9 665 | down 9 666 | down 1 667 | down 1 668 | down 7 669 | down 4 670 | down 7 671 | up 5 672 | forward 6 673 | down 9 674 | forward 7 675 | down 5 676 | down 4 677 | down 2 678 | down 4 679 | down 9 680 | forward 1 681 | down 9 682 | down 8 683 | forward 2 684 | up 7 685 | up 3 686 | forward 9 687 | forward 4 688 | down 8 689 | down 4 690 | forward 2 691 | down 8 692 | up 3 693 | forward 6 694 | forward 4 695 | down 2 696 | up 9 697 | down 5 698 | up 8 699 | up 6 700 | up 3 701 | down 2 702 | forward 6 703 | forward 4 704 | forward 7 705 | forward 2 706 | down 5 707 | down 2 708 | forward 2 709 | forward 6 710 | down 5 711 | down 4 712 | forward 8 713 | up 3 714 | forward 7 715 | down 1 716 | forward 5 717 | down 8 718 | down 9 719 | forward 5 720 | down 7 721 | forward 7 722 | up 6 723 | down 3 724 | forward 1 725 | down 2 726 | down 9 727 | down 2 728 | down 1 729 | forward 4 730 | up 5 731 | up 9 732 | forward 1 733 | down 5 734 | forward 4 735 | up 3 736 | up 5 737 | forward 7 738 | forward 5 739 | down 2 740 | down 8 741 | forward 5 742 | down 7 743 | up 8 744 | down 5 745 | down 6 746 | forward 8 747 | forward 9 748 | down 8 749 | up 3 750 | down 8 751 | down 2 752 | forward 8 753 | forward 8 754 | forward 4 755 | forward 9 756 | up 7 757 | up 1 758 | down 5 759 | down 8 760 | down 5 761 | forward 3 762 | forward 2 763 | down 8 764 | down 3 765 | down 2 766 | down 5 767 | forward 8 768 | up 3 769 | down 9 770 | up 4 771 | up 1 772 | up 8 773 | down 8 774 | forward 5 775 | down 2 776 | forward 4 777 | forward 1 778 | down 7 779 | forward 4 780 | forward 5 781 | up 2 782 | down 6 783 | up 9 784 | forward 1 785 | down 9 786 | forward 4 787 | down 7 788 | down 9 789 | up 9 790 | forward 2 791 | forward 7 792 | down 7 793 | forward 9 794 | forward 1 795 | forward 1 796 | down 7 797 | up 6 798 | up 3 799 | forward 2 800 | forward 6 801 | forward 9 802 | forward 3 803 | forward 4 804 | forward 9 805 | forward 9 806 | forward 9 807 | down 8 808 | up 2 809 | forward 7 810 | down 8 811 | down 3 812 | up 8 813 | down 8 814 | forward 1 815 | forward 9 816 | forward 2 817 | forward 3 818 | down 8 819 | forward 1 820 | forward 4 821 | down 9 822 | down 4 823 | up 7 824 | forward 5 825 | down 4 826 | forward 5 827 | down 2 828 | forward 6 829 | down 1 830 | up 9 831 | down 5 832 | up 5 833 | down 2 834 | up 1 835 | up 8 836 | down 3 837 | up 3 838 | down 8 839 | forward 4 840 | forward 1 841 | up 5 842 | forward 1 843 | down 5 844 | up 5 845 | forward 8 846 | down 1 847 | up 4 848 | forward 9 849 | forward 7 850 | up 1 851 | up 9 852 | forward 7 853 | forward 1 854 | up 5 855 | forward 6 856 | down 2 857 | up 5 858 | down 4 859 | down 6 860 | down 3 861 | forward 8 862 | down 7 863 | down 5 864 | down 7 865 | forward 1 866 | down 7 867 | up 5 868 | down 4 869 | down 4 870 | down 4 871 | forward 3 872 | forward 4 873 | up 6 874 | forward 8 875 | forward 2 876 | up 1 877 | forward 5 878 | forward 6 879 | forward 6 880 | up 2 881 | down 3 882 | forward 3 883 | up 8 884 | forward 6 885 | forward 5 886 | up 2 887 | up 5 888 | down 6 889 | down 8 890 | down 1 891 | forward 6 892 | down 3 893 | down 2 894 | forward 4 895 | down 4 896 | down 7 897 | forward 9 898 | forward 4 899 | forward 5 900 | down 8 901 | down 9 902 | up 4 903 | up 4 904 | down 5 905 | up 1 906 | up 6 907 | down 9 908 | forward 9 909 | forward 4 910 | forward 9 911 | forward 9 912 | down 5 913 | down 1 914 | up 9 915 | down 3 916 | up 5 917 | down 7 918 | forward 6 919 | forward 2 920 | down 5 921 | down 6 922 | forward 7 923 | forward 2 924 | up 9 925 | forward 6 926 | down 7 927 | up 4 928 | forward 1 929 | down 5 930 | forward 2 931 | forward 1 932 | down 6 933 | down 1 934 | down 4 935 | forward 8 936 | forward 1 937 | down 5 938 | down 8 939 | down 3 940 | forward 4 941 | down 2 942 | forward 9 943 | up 1 944 | forward 8 945 | down 4 946 | down 3 947 | down 1 948 | forward 5 949 | forward 9 950 | down 3 951 | forward 6 952 | up 6 953 | up 9 954 | forward 8 955 | forward 2 956 | down 9 957 | forward 3 958 | down 4 959 | down 5 960 | down 4 961 | forward 2 962 | forward 6 963 | down 9 964 | down 5 965 | forward 6 966 | forward 3 967 | forward 5 968 | forward 6 969 | forward 5 970 | forward 1 971 | up 4 972 | up 1 973 | down 2 974 | up 6 975 | down 5 976 | down 1 977 | forward 9 978 | down 1 979 | down 2 980 | forward 6 981 | up 2 982 | down 4 983 | up 3 984 | forward 8 985 | down 4 986 | down 4 987 | down 6 988 | up 1 989 | down 7 990 | up 4 991 | down 6 992 | up 7 993 | up 6 994 | down 5 995 | forward 3 996 | forward 4 997 | up 5 998 | down 2 999 | down 9 1000 | forward 9 -------------------------------------------------------------------------------- /day19/input.txt: -------------------------------------------------------------------------------- 1 | --- scanner 0 --- 2 | 536,703,543 3 | -132,-41,-64 4 | -429,350,-809 5 | -477,567,455 6 | -369,-732,-732 7 | -806,-680,810 8 | 502,729,469 9 | -417,400,-831 10 | 497,-739,-564 11 | -545,-726,-743 12 | 271,357,-605 13 | 13,-26,94 14 | 508,-654,-647 15 | -581,-685,774 16 | 396,-908,355 17 | -481,568,418 18 | -634,-665,910 19 | 306,410,-668 20 | 540,739,539 21 | 465,-656,-423 22 | -474,-628,-795 23 | -463,568,426 24 | 254,306,-662 25 | 358,-788,353 26 | -396,313,-691 27 | 251,-873,452 28 | 29 | --- scanner 1 --- 30 | 405,377,-919 31 | -471,604,350 32 | 479,506,644 33 | 495,326,707 34 | -407,-663,-846 35 | 618,-537,318 36 | -584,506,-618 37 | -577,-375,640 38 | 682,-442,283 39 | -579,-587,598 40 | 612,361,-928 41 | -253,-680,-729 42 | 512,382,-895 43 | 531,379,751 44 | -468,-460,659 45 | -262,-699,-913 46 | 974,-376,-550 47 | 539,-333,326 48 | 917,-437,-630 49 | -422,787,372 50 | 48,7,-59 51 | -451,618,404 52 | -697,390,-626 53 | -766,485,-587 54 | 971,-556,-663 55 | 56 | --- scanner 2 --- 57 | -652,-598,521 58 | 680,708,-671 59 | 401,-847,-328 60 | -666,588,522 61 | -629,-292,-571 62 | 256,-750,-363 63 | -576,-428,-551 64 | -698,690,-828 65 | 640,385,384 66 | 698,679,-614 67 | -801,-392,-556 68 | 490,-475,680 69 | -594,-543,549 70 | 27,-15,66 71 | -878,546,524 72 | -703,476,-864 73 | 741,661,-790 74 | -793,527,633 75 | 506,-675,668 76 | -736,691,-860 77 | -646,-597,737 78 | 650,579,455 79 | 363,-849,-448 80 | -77,-44,-102 81 | 636,387,485 82 | 609,-565,657 83 | 84 | --- scanner 3 --- 85 | -694,-480,675 86 | -79,48,-39 87 | -713,754,292 88 | 329,-686,-566 89 | 352,-717,-653 90 | 689,385,454 91 | -736,862,-562 92 | -619,615,350 93 | 687,515,-478 94 | 754,359,540 95 | -741,-551,707 96 | -416,-641,-826 97 | 780,-406,714 98 | 757,427,547 99 | -766,670,-548 100 | 376,-703,-591 101 | -676,-675,645 102 | 616,-364,628 103 | -413,-651,-750 104 | -645,601,324 105 | -837,864,-558 106 | 618,546,-543 107 | 651,-444,702 108 | -438,-700,-839 109 | 735,493,-571 110 | 111 | --- scanner 4 --- 112 | -530,746,312 113 | 786,-443,556 114 | -889,-559,548 115 | 707,-625,-700 116 | -597,746,-565 117 | -695,733,324 118 | 797,-456,613 119 | 521,468,-520 120 | 798,-448,530 121 | -820,-811,-882 122 | -905,-712,-989 123 | 700,666,439 124 | 759,795,432 125 | 637,796,456 126 | -877,-533,314 127 | -887,-526,362 128 | 671,-621,-704 129 | -575,696,330 130 | -940,-809,-844 131 | -478,699,-504 132 | -654,717,-547 133 | -56,111,-123 134 | 529,444,-427 135 | 618,407,-518 136 | 697,-695,-738 137 | 138 | --- scanner 5 --- 139 | -622,-664,638 140 | 91,56,-46 141 | -584,-588,503 142 | -597,-542,-844 143 | 637,-732,382 144 | 541,-389,-695 145 | 608,849,773 146 | -824,472,329 147 | -715,664,-901 148 | -807,472,398 149 | 696,824,658 150 | -748,513,423 151 | 734,-704,553 152 | -603,-571,-996 153 | 702,-641,519 154 | -564,648,-902 155 | -546,-560,-802 156 | 529,757,-875 157 | -774,670,-893 158 | 710,934,780 159 | -633,-647,616 160 | 45,186,-187 161 | 571,805,-747 162 | 469,-300,-758 163 | 548,722,-801 164 | 470,-365,-800 165 | 166 | --- scanner 6 --- 167 | -63,90,49 168 | 498,853,-791 169 | 578,-569,-624 170 | -655,-638,533 171 | 625,-555,-405 172 | 612,-558,-546 173 | 481,703,-791 174 | 472,508,699 175 | -676,-594,581 176 | 641,-783,554 177 | 689,489,688 178 | -597,648,491 179 | -588,829,-432 180 | 447,-795,466 181 | -611,-448,-552 182 | -628,702,-523 183 | 517,666,-715 184 | -730,-425,-642 185 | -606,719,-512 186 | -714,-437,-442 187 | -537,611,499 188 | -462,665,425 189 | 597,478,703 190 | 460,-784,616 191 | -648,-556,677 192 | 193 | --- scanner 7 --- 194 | 845,881,-301 195 | -501,-349,486 196 | -315,-608,-344 197 | -480,685,-388 198 | 718,980,-308 199 | 915,979,627 200 | -279,-529,-320 201 | 749,-436,411 202 | -508,-323,638 203 | -557,-346,709 204 | 744,-481,476 205 | 738,-636,412 206 | -431,775,-306 207 | -486,759,-520 208 | 378,-599,-409 209 | -575,569,537 210 | 538,-579,-380 211 | 94,37,37 212 | -656,696,463 213 | 931,951,534 214 | 931,865,728 215 | 448,-570,-525 216 | -739,579,511 217 | -301,-469,-277 218 | 782,925,-452 219 | 220 | --- scanner 8 --- 221 | -642,587,781 222 | 449,768,-502 223 | -541,-248,454 224 | -652,688,-666 225 | -657,-301,345 226 | 388,565,306 227 | -711,575,-617 228 | -597,592,716 229 | 31,60,-133 230 | -705,-303,534 231 | -728,553,-628 232 | 518,471,325 233 | -449,-629,-686 234 | -462,-608,-643 235 | 399,395,424 236 | 573,-579,-519 237 | -49,145,4 238 | 485,-560,410 239 | 365,-564,556 240 | 408,793,-443 241 | -580,-592,-693 242 | 542,-671,-541 243 | 408,862,-426 244 | 380,-463,470 245 | -442,598,780 246 | 580,-773,-513 247 | 248 | --- scanner 9 --- 249 | 511,-520,557 250 | 831,490,487 251 | -549,-659,-680 252 | 536,-615,-490 253 | 165,-84,33 254 | 652,-552,474 255 | -516,602,-544 256 | -439,-556,-691 257 | -267,-451,305 258 | -822,579,548 259 | -571,544,-572 260 | -16,-6,-106 261 | 841,452,-616 262 | -517,596,-760 263 | -364,-306,340 264 | 584,-594,-534 265 | 820,314,481 266 | 680,-622,-572 267 | 883,419,585 268 | -722,751,533 269 | -639,-540,-703 270 | 735,-563,559 271 | 947,393,-650 272 | -686,526,528 273 | 905,520,-588 274 | -265,-413,425 275 | 276 | --- scanner 10 --- 277 | -737,650,-388 278 | 799,760,694 279 | -389,-453,768 280 | -667,-803,-543 281 | 537,-419,977 282 | 573,-564,910 283 | 699,461,-254 284 | -644,698,-366 285 | -657,-874,-737 286 | 556,-410,793 287 | -672,581,-419 288 | -653,-773,-735 289 | 680,814,727 290 | 78,-167,23 291 | -376,-475,827 292 | 861,-734,-576 293 | 649,-736,-534 294 | 776,-625,-595 295 | -649,292,813 296 | 860,817,614 297 | -624,339,830 298 | 50,-20,162 299 | -465,-450,778 300 | -562,315,844 301 | 903,382,-262 302 | 794,525,-219 303 | 304 | --- scanner 11 --- 305 | 99,76,34 306 | -676,680,608 307 | -416,-818,449 308 | -383,-733,-582 309 | -278,-673,-485 310 | -263,-587,-586 311 | -297,-719,373 312 | 610,574,866 313 | 544,-363,576 314 | 743,689,-672 315 | -817,391,-552 316 | -607,706,535 317 | 601,429,776 318 | -805,494,-602 319 | -779,332,-498 320 | 699,-427,570 321 | 703,798,-570 322 | 759,-798,-323 323 | 643,-689,-270 324 | -605,648,465 325 | 648,653,-655 326 | -286,-837,543 327 | -21,-98,124 328 | 581,458,936 329 | 807,-609,-325 330 | 744,-362,565 331 | 332 | --- scanner 12 --- 333 | -425,-551,749 334 | 399,-500,-745 335 | 621,-564,617 336 | 458,551,789 337 | -771,404,712 338 | -635,-782,-410 339 | 141,-60,-11 340 | -407,-500,691 341 | 427,311,-461 342 | 434,438,-362 343 | -786,391,773 344 | -533,-750,-406 345 | 578,374,-417 346 | 420,485,830 347 | 376,378,782 348 | -602,225,-477 349 | 535,-509,559 350 | -733,594,734 351 | 652,-499,714 352 | -466,-660,638 353 | 375,-461,-524 354 | -501,241,-363 355 | 13,-15,-141 356 | 392,-416,-592 357 | -585,-935,-464 358 | -408,225,-391 359 | 360 | --- scanner 13 --- 361 | -869,-562,284 362 | -626,-660,-761 363 | 863,541,-592 364 | -615,-577,-676 365 | 594,-454,-831 366 | -713,476,667 367 | 915,554,-452 368 | 621,-462,713 369 | 528,750,450 370 | 680,-516,627 371 | -640,407,641 372 | -783,478,609 373 | 866,578,-609 374 | -705,797,-876 375 | -875,786,-758 376 | 662,-561,828 377 | -658,-801,-678 378 | 524,593,486 379 | -852,-619,335 380 | -799,667,-857 381 | -817,-556,388 382 | 479,-362,-887 383 | 490,705,572 384 | 101,-76,-131 385 | -40,-1,16 386 | 414,-474,-816 387 | 388 | --- scanner 14 --- 389 | 441,817,-678 390 | -598,650,753 391 | 371,-553,781 392 | -510,-749,-608 393 | 9,-9,185 394 | 364,-412,661 395 | -698,-767,-537 396 | -695,787,-546 397 | -93,144,106 398 | 676,-367,-546 399 | -564,746,-667 400 | 478,752,-535 401 | -588,-350,394 402 | 565,773,-725 403 | -587,-306,537 404 | -678,698,-692 405 | -773,-762,-605 406 | -393,632,689 407 | 597,749,893 408 | 827,-282,-517 409 | -490,578,681 410 | 380,-405,668 411 | 808,-318,-662 412 | 578,692,850 413 | 579,917,825 414 | -578,-442,497 415 | 416 | --- scanner 15 --- 417 | 711,434,636 418 | -814,919,616 419 | -367,796,-569 420 | 667,-597,612 421 | 637,-360,-736 422 | 668,-381,618 423 | 699,-371,-662 424 | -351,789,-562 425 | 591,759,-398 426 | 786,439,704 427 | 128,62,-70 428 | -793,-527,-586 429 | 722,-569,670 430 | -754,-553,694 431 | 600,895,-438 432 | 601,851,-295 433 | -796,-491,821 434 | -663,834,645 435 | -795,883,761 436 | -690,-470,-654 437 | -728,-676,-612 438 | -690,-525,762 439 | 639,-287,-734 440 | -358,648,-682 441 | 523,452,707 442 | 443 | --- scanner 16 --- 444 | 509,-793,667 445 | 878,553,565 446 | -582,760,-790 447 | -599,-400,-777 448 | 581,-549,-837 449 | -498,-416,-891 450 | -405,-400,-863 451 | -530,575,-848 452 | 769,655,525 453 | -8,-11,-79 454 | 538,-953,687 455 | 90,-139,81 456 | -529,308,461 457 | 402,325,-509 458 | -282,-582,524 459 | -347,-587,569 460 | 654,-883,658 461 | -718,306,509 462 | -609,253,625 463 | -283,-593,724 464 | -632,607,-844 465 | 430,-486,-793 466 | 395,241,-662 467 | 437,-613,-892 468 | 733,638,620 469 | 378,286,-730 470 | 471 | --- scanner 17 --- 472 | 754,602,-677 473 | -722,-580,-369 474 | -439,722,669 475 | -372,731,-647 476 | 16,-1,-34 477 | 164,118,125 478 | 433,-796,-390 479 | 474,-459,828 480 | 943,619,739 481 | -765,-605,576 482 | -402,923,-633 483 | 697,631,-695 484 | 873,649,-738 485 | -700,-639,-356 486 | 592,-518,899 487 | -756,-789,557 488 | 566,-719,-309 489 | 475,-540,761 490 | -725,-590,-445 491 | 692,-807,-381 492 | -611,-722,593 493 | -550,783,796 494 | 911,620,701 495 | -441,764,881 496 | -301,925,-637 497 | 947,834,706 498 | 499 | --- scanner 18 --- 500 | 113,-179,93 501 | -709,565,-575 502 | -585,-728,588 503 | 812,527,-496 504 | -496,315,704 505 | -367,364,615 506 | 939,-532,762 507 | 727,472,-351 508 | 701,704,557 509 | -312,-886,-799 510 | 944,-633,873 511 | -779,594,-691 512 | -533,-891,548 513 | 499,-602,-827 514 | -608,-769,451 515 | -375,-930,-648 516 | -619,574,-720 517 | 829,432,-460 518 | 460,-823,-851 519 | 757,693,547 520 | 415,-755,-834 521 | 950,-664,733 522 | -439,-985,-792 523 | 702,691,743 524 | -341,400,702 525 | 526 | --- scanner 19 --- 527 | 765,-723,-476 528 | -795,553,792 529 | 640,682,-495 530 | 138,123,77 531 | 648,-491,767 532 | 617,736,-578 533 | -556,-542,581 534 | -679,-488,-787 535 | -738,-463,-828 536 | -755,-394,-828 537 | 508,578,559 538 | 779,-845,-366 539 | -638,-549,725 540 | 489,795,570 541 | 611,-431,759 542 | 665,-356,833 543 | 478,703,555 544 | 80,10,-59 545 | -594,-570,677 546 | -783,747,704 547 | -705,828,-630 548 | 677,-838,-451 549 | -784,566,642 550 | -495,837,-652 551 | 598,810,-543 552 | -646,836,-636 553 | 554 | --- scanner 20 --- 555 | 698,-671,896 556 | -629,-578,570 557 | 882,-690,887 558 | 633,-486,-344 559 | 815,-654,742 560 | 862,582,-466 561 | -307,396,-533 562 | -671,-366,572 563 | 556,494,383 564 | -327,471,-605 565 | -403,796,727 566 | -526,-508,-812 567 | -690,-451,681 568 | -48,50,4 569 | 595,399,452 570 | -741,-541,-816 571 | -435,627,698 572 | -381,613,678 573 | 611,-348,-461 574 | -527,-546,-780 575 | 587,515,565 576 | 887,614,-414 577 | -361,524,-418 578 | 552,-419,-343 579 | 867,468,-504 580 | 581 | --- scanner 21 --- 582 | 591,695,-643 583 | -461,-434,378 584 | 876,-525,845 585 | 447,688,-725 586 | -609,715,615 587 | 858,-320,-565 588 | -724,-437,365 589 | 752,-379,-599 590 | 725,-496,760 591 | 816,-447,-627 592 | 413,806,524 593 | -598,737,632 594 | -528,629,-524 595 | -660,-471,-643 596 | -649,-505,360 597 | 405,746,561 598 | -606,-523,-455 599 | -605,-529,-671 600 | -638,732,-535 601 | 339,881,578 602 | -110,154,-71 603 | 857,-380,809 604 | 38,67,-3 605 | -518,755,742 606 | 495,667,-681 607 | -728,613,-512 608 | 609 | --- scanner 22 --- 610 | 417,869,-670 611 | -390,-523,-643 612 | 668,-601,466 613 | -449,460,555 614 | -411,652,-704 615 | 757,407,838 616 | -332,-429,-504 617 | -399,817,-717 618 | -14,26,-96 619 | -635,458,588 620 | 549,-578,556 621 | -401,470,562 622 | -674,-468,562 623 | -687,-471,703 624 | -364,-497,-657 625 | 460,693,-688 626 | 508,-376,-588 627 | 902,442,741 628 | 478,750,-717 629 | 518,-305,-394 630 | 652,-589,666 631 | 109,117,38 632 | -417,772,-667 633 | 795,527,840 634 | -640,-457,484 635 | 522,-406,-396 636 | 637 | --- scanner 23 --- 638 | -800,-816,-415 639 | 486,376,-362 640 | -411,496,636 641 | 260,419,326 642 | -938,-671,519 643 | 1,-24,20 644 | 359,-713,278 645 | -930,-835,-509 646 | -611,650,-431 647 | 668,-637,-556 648 | 429,325,-345 649 | -833,-731,616 650 | 423,429,-397 651 | 282,369,338 652 | -953,-585,620 653 | 400,332,305 654 | 296,-609,383 655 | -437,334,532 656 | -919,-717,-339 657 | 348,-707,454 658 | 527,-720,-588 659 | 444,-635,-599 660 | -540,682,-574 661 | -186,11,-59 662 | -399,393,586 663 | -609,708,-501 664 | 665 | --- scanner 24 --- 666 | 661,560,-615 667 | -838,-878,-425 668 | 756,-980,519 669 | -430,-499,528 670 | -840,792,-299 671 | -891,-834,-389 672 | 730,337,599 673 | -711,491,690 674 | -613,-477,577 675 | -835,768,-406 676 | -827,499,803 677 | 792,592,-663 678 | -711,-771,-373 679 | 656,286,631 680 | -856,801,-506 681 | -42,-81,88 682 | 841,216,626 683 | -599,-531,557 684 | 767,-854,387 685 | 754,-461,-726 686 | -732,460,872 687 | 859,-869,436 688 | 668,-426,-620 689 | 626,-548,-657 690 | 802,511,-703 691 | 692 | --- scanner 25 --- 693 | 871,758,-518 694 | -441,-709,335 695 | 458,576,380 696 | 704,-742,-632 697 | -721,571,786 698 | -803,-452,-835 699 | -752,658,763 700 | -711,565,-686 701 | 828,638,-529 702 | -687,377,-660 703 | 392,-542,358 704 | -686,530,-584 705 | 818,761,-520 706 | -888,-342,-883 707 | 480,483,428 708 | -798,-414,-880 709 | 324,-535,361 710 | -399,-623,499 711 | -54,-43,48 712 | 511,548,497 713 | 350,-449,426 714 | 807,-776,-756 715 | -738,596,739 716 | 81,137,-43 717 | 716,-700,-860 718 | -479,-697,464 719 | 720 | --- scanner 26 --- 721 | -901,-451,391 722 | -534,-435,-744 723 | -383,810,622 724 | -7,71,53 725 | 474,684,458 726 | -861,602,-891 727 | -769,-567,440 728 | -571,-578,-679 729 | -457,735,676 730 | 605,-576,840 731 | -920,-596,355 732 | 417,-505,822 733 | 680,-508,835 734 | 384,612,-707 735 | 471,-446,-673 736 | 462,781,-698 737 | 565,644,585 738 | -864,517,-869 739 | 554,666,568 740 | -909,737,-873 741 | -658,-388,-700 742 | -449,675,639 743 | 585,-421,-625 744 | 602,-567,-714 745 | 397,746,-782 746 | 747 | --- scanner 27 --- 748 | -490,-562,-654 749 | 501,516,490 750 | -310,-612,762 751 | 560,738,-569 752 | 587,-506,-667 753 | -782,970,-551 754 | -729,935,-614 755 | -289,-544,-609 756 | 424,433,614 757 | 606,-412,-491 758 | -833,987,-608 759 | 378,-468,689 760 | -404,-503,-708 761 | 391,546,639 762 | 487,738,-654 763 | -436,705,597 764 | 451,-491,621 765 | -400,701,593 766 | -321,-555,775 767 | 567,-397,668 768 | 81,40,90 769 | 582,667,-630 770 | -410,739,523 771 | -309,-529,770 772 | 657,-413,-678 773 | 774 | --- scanner 28 --- 775 | 69,84,-59 776 | -289,-502,-551 777 | 595,-623,583 778 | -456,920,-639 779 | 583,-423,567 780 | 778,439,713 781 | -576,755,732 782 | 714,-491,-517 783 | -307,-690,-480 784 | -693,808,704 785 | 879,437,717 786 | 739,598,-801 787 | -377,912,-843 788 | -645,786,797 789 | 741,640,-589 790 | -544,-542,669 791 | 742,-546,-575 792 | -520,955,-734 793 | 606,-513,686 794 | 526,-545,-569 795 | -671,-633,709 796 | -561,-553,691 797 | -294,-427,-483 798 | 808,631,727 799 | 630,579,-716 800 | 801 | --- scanner 29 --- 802 | 554,-452,430 803 | 712,317,-664 804 | 554,-470,422 805 | -577,514,-619 806 | -735,-733,754 807 | -625,-635,-349 808 | 419,547,547 809 | -441,819,564 810 | -504,514,-704 811 | -518,736,440 812 | 809,-385,-687 813 | 30,-54,-66 814 | 722,-406,-827 815 | -599,585,-680 816 | 772,-418,-805 817 | -123,-145,56 818 | 765,282,-601 819 | -662,-695,652 820 | -660,-788,804 821 | 383,551,543 822 | -650,-675,-301 823 | -723,-747,-314 824 | -408,706,589 825 | 555,-466,459 826 | 393,513,473 827 | -30,28,95 828 | 816,265,-658 829 | 830 | --- scanner 30 --- 831 | 648,439,-720 832 | -883,-704,-653 833 | 760,676,623 834 | 681,-717,482 835 | 288,-461,-535 836 | 739,-762,425 837 | 752,755,827 838 | -682,-622,380 839 | -665,-711,526 840 | 278,-470,-658 841 | -587,838,467 842 | -793,461,-725 843 | 588,-655,448 844 | -850,825,464 845 | -702,588,-685 846 | -662,843,535 847 | -870,-779,-787 848 | 795,612,718 849 | -796,-670,405 850 | 595,556,-748 851 | 5,-51,26 852 | 235,-459,-538 853 | -131,33,-79 854 | -805,-695,-822 855 | -713,571,-707 856 | 626,487,-813 -------------------------------------------------------------------------------- /day3/input.txt: -------------------------------------------------------------------------------- 1 | 000110000001 2 | 011011001101 3 | 001101100111 4 | 001101011001 5 | 110111011101 6 | 110011101010 7 | 111101010001 8 | 010100111101 9 | 011000011000 10 | 001110110011 11 | 001100010110 12 | 110111101100 13 | 110001111100 14 | 001011111100 15 | 000000011010 16 | 110101100111 17 | 011000011111 18 | 011000000111 19 | 011111000110 20 | 100101110111 21 | 010101001110 22 | 111101000011 23 | 010010010110 24 | 100100011111 25 | 101011001110 26 | 001111110000 27 | 110000011111 28 | 110000011000 29 | 011001111100 30 | 010010001101 31 | 000111001110 32 | 110111001110 33 | 110001010101 34 | 100111011001 35 | 000101110000 36 | 110001011100 37 | 111101010010 38 | 101011000001 39 | 001101001111 40 | 110111101010 41 | 101111111000 42 | 110101000110 43 | 011111001001 44 | 001110100001 45 | 010100110111 46 | 110100000110 47 | 101010110010 48 | 100100101110 49 | 101111011110 50 | 000110110101 51 | 011011110101 52 | 111001011110 53 | 110110100111 54 | 000100010001 55 | 001101010110 56 | 100011000110 57 | 001110010010 58 | 010111110111 59 | 011010011101 60 | 110000011100 61 | 010100001001 62 | 000110100000 63 | 101001010000 64 | 000001110000 65 | 101110010011 66 | 010011100111 67 | 010011011000 68 | 110111011111 69 | 000111010010 70 | 101010111010 71 | 111001100100 72 | 101110100011 73 | 111101111110 74 | 010111111000 75 | 010010001111 76 | 110010000011 77 | 001110000010 78 | 100101111110 79 | 000100101001 80 | 101101010000 81 | 111111010000 82 | 101010011000 83 | 011100100001 84 | 011101101000 85 | 001010010100 86 | 010010100011 87 | 110011111111 88 | 110100011001 89 | 111010011110 90 | 011110001101 91 | 011010011100 92 | 100100000001 93 | 111111001010 94 | 110100110011 95 | 110100011111 96 | 100010001110 97 | 101000111100 98 | 100001110010 99 | 110101010011 100 | 101010011101 101 | 011010011010 102 | 101110101101 103 | 001100011010 104 | 101001010101 105 | 101010000100 106 | 000110101010 107 | 100000111100 108 | 000111111100 109 | 000001001011 110 | 010010111100 111 | 011000111001 112 | 111010101100 113 | 010011100010 114 | 010100110001 115 | 001100111011 116 | 101100001111 117 | 111010101111 118 | 010001000011 119 | 000001100010 120 | 000100001011 121 | 100110011011 122 | 101100001110 123 | 000010110100 124 | 011000101011 125 | 010011011100 126 | 110101010000 127 | 101101101100 128 | 101001110000 129 | 010111010011 130 | 110101110001 131 | 011000001000 132 | 011101010010 133 | 111011111110 134 | 010010000110 135 | 110000111000 136 | 101000000110 137 | 011100110000 138 | 111001111010 139 | 110000001100 140 | 101011111110 141 | 100001111100 142 | 011011100110 143 | 101000001101 144 | 001011110011 145 | 111100100011 146 | 101111000111 147 | 101000000001 148 | 001001011010 149 | 010111111010 150 | 101010111001 151 | 011110101001 152 | 101100111101 153 | 011100000010 154 | 000110001111 155 | 111100110101 156 | 100011100010 157 | 000110010100 158 | 011000000011 159 | 010011001011 160 | 000001101111 161 | 101011101101 162 | 100100100101 163 | 011001110110 164 | 010100000000 165 | 100100010001 166 | 001100000100 167 | 100000111010 168 | 101001011001 169 | 010010111001 170 | 110000101010 171 | 001101010101 172 | 110110011100 173 | 010000000011 174 | 111100011000 175 | 000101111110 176 | 100010110101 177 | 101111010000 178 | 000010100010 179 | 101101001010 180 | 011111000000 181 | 011000100100 182 | 110010100110 183 | 010001110011 184 | 010101101101 185 | 001011100000 186 | 001000110110 187 | 001000110111 188 | 110100111110 189 | 110010110100 190 | 101010100111 191 | 000111011001 192 | 111000101101 193 | 110000010110 194 | 010011101010 195 | 110100111011 196 | 100110010100 197 | 100111000011 198 | 011110111111 199 | 010010000111 200 | 111100111110 201 | 001010111101 202 | 000011001110 203 | 000110010101 204 | 111100110011 205 | 101111111001 206 | 101001111011 207 | 111010110000 208 | 000001010101 209 | 100010011001 210 | 111110110010 211 | 110100101100 212 | 100001011110 213 | 100001000011 214 | 101111000011 215 | 101111110100 216 | 111010000010 217 | 001010010110 218 | 010001000110 219 | 100010000101 220 | 111101111010 221 | 000101111111 222 | 010110110100 223 | 110111111110 224 | 011010101011 225 | 100000110011 226 | 000000101001 227 | 010010101111 228 | 010001001010 229 | 000101010100 230 | 101110111010 231 | 101001000000 232 | 001010101111 233 | 011110100110 234 | 110101011001 235 | 100111101101 236 | 110001001001 237 | 110100001010 238 | 100100101001 239 | 110111010011 240 | 011010001011 241 | 011001001101 242 | 110100010001 243 | 010100001100 244 | 011011000001 245 | 110100011100 246 | 001110111111 247 | 111001110010 248 | 001110010000 249 | 011100001110 250 | 001111110001 251 | 001101010111 252 | 111110011100 253 | 111100111010 254 | 010100010100 255 | 000011001010 256 | 011110001010 257 | 111101010011 258 | 100111001010 259 | 010110110011 260 | 000101000000 261 | 000110011010 262 | 100100001111 263 | 000100111111 264 | 010100010101 265 | 001110100011 266 | 100111000100 267 | 100001101110 268 | 011010011110 269 | 001111010101 270 | 111000001100 271 | 100111110110 272 | 101110001100 273 | 101011000111 274 | 001010110010 275 | 100011011100 276 | 110000010000 277 | 101001101011 278 | 111011011000 279 | 000101101001 280 | 011001111011 281 | 101011001111 282 | 001111111111 283 | 110000101011 284 | 111111100011 285 | 101010101111 286 | 001001010001 287 | 011111010001 288 | 001011101110 289 | 011010011011 290 | 011000001011 291 | 100000100000 292 | 001011110110 293 | 011000100011 294 | 001010011010 295 | 000010111111 296 | 001110001111 297 | 111110001100 298 | 010110100011 299 | 110101100010 300 | 100111110000 301 | 010000101011 302 | 011100011111 303 | 001100101010 304 | 101110110100 305 | 100101000111 306 | 111111111010 307 | 000001000001 308 | 110111011001 309 | 010011000000 310 | 101100000101 311 | 110000100100 312 | 110100100101 313 | 101011010010 314 | 101001000101 315 | 110001001111 316 | 010010011010 317 | 000110110111 318 | 011010110001 319 | 001101001001 320 | 010110101000 321 | 101000011000 322 | 110010011010 323 | 100101011111 324 | 001101110011 325 | 110001110001 326 | 011110000110 327 | 111011100101 328 | 001100111001 329 | 001011011011 330 | 001011110001 331 | 010001111101 332 | 011000101001 333 | 100100000110 334 | 011000101111 335 | 001010110100 336 | 000100101010 337 | 111011010110 338 | 100111000000 339 | 001000111010 340 | 101101001111 341 | 000110111010 342 | 001111100001 343 | 011110011001 344 | 100011000101 345 | 001010010011 346 | 110011100110 347 | 010010001011 348 | 110101101110 349 | 111100100101 350 | 101100100010 351 | 111010111101 352 | 000000000011 353 | 011011001110 354 | 101110000001 355 | 000111111000 356 | 100000110001 357 | 101101100111 358 | 001001011001 359 | 101100010010 360 | 001000011100 361 | 111011111100 362 | 010000100011 363 | 111010111100 364 | 011001101111 365 | 100011001111 366 | 011001111010 367 | 110110100101 368 | 010110100110 369 | 011110101101 370 | 011101110001 371 | 111000100101 372 | 000010000000 373 | 100110111001 374 | 000101000001 375 | 000001101100 376 | 011010000100 377 | 111000101001 378 | 111100111111 379 | 100110000110 380 | 100010001010 381 | 011110001000 382 | 100001100100 383 | 101101101010 384 | 101111010001 385 | 010001111100 386 | 001010111001 387 | 001101110111 388 | 010100101100 389 | 100011011101 390 | 010100111000 391 | 000110000000 392 | 110101101010 393 | 010100000101 394 | 101110111100 395 | 001010110000 396 | 000000010101 397 | 000100011000 398 | 011010110100 399 | 010000000010 400 | 111101100011 401 | 000111101001 402 | 011101011100 403 | 101000101101 404 | 110110101011 405 | 011010110011 406 | 011001101010 407 | 100000000011 408 | 101001111111 409 | 111010110100 410 | 010000011100 411 | 011011100000 412 | 110011011000 413 | 111011101111 414 | 100010110110 415 | 010000100111 416 | 110101110101 417 | 100010111001 418 | 011011101000 419 | 011010000001 420 | 001001111110 421 | 100010010001 422 | 010101000110 423 | 111111110010 424 | 101011011110 425 | 010011110110 426 | 000010010100 427 | 100011101111 428 | 001001110110 429 | 000100110100 430 | 100101110110 431 | 011010111001 432 | 010010101110 433 | 110010100011 434 | 011010101010 435 | 000101111000 436 | 111011110011 437 | 100111101110 438 | 101111101001 439 | 010111100010 440 | 111011001011 441 | 111110011110 442 | 110110010110 443 | 010110010111 444 | 011111001100 445 | 110111110010 446 | 110011111000 447 | 001110111101 448 | 111100111000 449 | 000100000010 450 | 110101111110 451 | 010111101101 452 | 111001001010 453 | 000010011100 454 | 110101100100 455 | 111000011110 456 | 010110000000 457 | 011100010011 458 | 011110010100 459 | 101000100111 460 | 111011110101 461 | 000100010000 462 | 000110110011 463 | 100011001011 464 | 111010100000 465 | 010100110101 466 | 001000000101 467 | 010001101100 468 | 010110000101 469 | 100100101111 470 | 011101111110 471 | 000011110000 472 | 000011010011 473 | 101111111110 474 | 101001101010 475 | 000010100011 476 | 010100101010 477 | 001111001110 478 | 011000001001 479 | 010001110100 480 | 010111011110 481 | 100000111111 482 | 101100010101 483 | 111101000110 484 | 110111101111 485 | 011010010010 486 | 011100011100 487 | 001111010010 488 | 111001101000 489 | 110110111010 490 | 101110000111 491 | 011100101100 492 | 011100001010 493 | 110101011101 494 | 011100010010 495 | 010101010010 496 | 000001111101 497 | 110100110111 498 | 011111100111 499 | 111101011110 500 | 110110000110 501 | 100110001011 502 | 111110000001 503 | 010001010011 504 | 101001110110 505 | 011101011101 506 | 010011011110 507 | 000100000000 508 | 100110010001 509 | 000011100110 510 | 101111100001 511 | 101100101010 512 | 001010101110 513 | 001111001101 514 | 110000000111 515 | 110010100001 516 | 011100000111 517 | 100111100111 518 | 101001011111 519 | 110000100011 520 | 111001000111 521 | 010101111010 522 | 110111100100 523 | 001010101100 524 | 001011110100 525 | 001010010111 526 | 110001001000 527 | 110010011001 528 | 110111011100 529 | 001110000011 530 | 010001000010 531 | 100000000101 532 | 110001101001 533 | 000101010111 534 | 101010110101 535 | 100000010000 536 | 000000111100 537 | 011011100100 538 | 110010001110 539 | 110110100000 540 | 101100001100 541 | 110010110111 542 | 010001100010 543 | 101110100010 544 | 001101101101 545 | 010100110000 546 | 010010100000 547 | 011101110100 548 | 100011011001 549 | 010110111101 550 | 010110011011 551 | 011111011111 552 | 001000000000 553 | 001101110101 554 | 010000010101 555 | 000101001000 556 | 011011100101 557 | 001010000101 558 | 110010001101 559 | 000001000011 560 | 001101001110 561 | 000101100010 562 | 010110100001 563 | 010111110011 564 | 011000100111 565 | 100001101011 566 | 100100100011 567 | 111100011001 568 | 010010101000 569 | 101010000010 570 | 010011000001 571 | 100000000010 572 | 010011101011 573 | 101110100111 574 | 111101101011 575 | 011010001111 576 | 001000011000 577 | 011111110111 578 | 101111011100 579 | 011011011111 580 | 110111100010 581 | 010010110001 582 | 111100010111 583 | 111000001111 584 | 101100010011 585 | 010101001101 586 | 110101100001 587 | 010111010110 588 | 110000001111 589 | 000111000000 590 | 110010010001 591 | 001110110101 592 | 101000010010 593 | 010110001100 594 | 001101101010 595 | 110110110110 596 | 000000000111 597 | 011010010000 598 | 011001010111 599 | 001010101011 600 | 001001100011 601 | 001111010110 602 | 000000100111 603 | 000000010100 604 | 001001110011 605 | 010111000010 606 | 010000001100 607 | 101111010111 608 | 101001110100 609 | 100011010111 610 | 000111110100 611 | 011101111010 612 | 000111000010 613 | 011100111100 614 | 011011110100 615 | 101000110011 616 | 010101110111 617 | 111101101000 618 | 010010011011 619 | 000101011111 620 | 010000000110 621 | 011110100101 622 | 111000000100 623 | 010110110101 624 | 010110111001 625 | 101110010000 626 | 010111001111 627 | 001001000110 628 | 010100010000 629 | 101100100111 630 | 101100001000 631 | 110110001001 632 | 011001001010 633 | 011001001110 634 | 110011101001 635 | 010100101111 636 | 111101001000 637 | 100000101100 638 | 111000011000 639 | 011000011100 640 | 111111010001 641 | 111100100100 642 | 011000111110 643 | 010011010000 644 | 100110101100 645 | 110000100001 646 | 001101010011 647 | 011000101110 648 | 000110010000 649 | 011010101100 650 | 001110001010 651 | 010101000001 652 | 101010010101 653 | 100000010111 654 | 000100110101 655 | 110111010110 656 | 101101101011 657 | 100101100101 658 | 101010011110 659 | 111001000100 660 | 011101100111 661 | 010000110101 662 | 100111010110 663 | 010011111110 664 | 111011100100 665 | 100010101101 666 | 010110100101 667 | 100011100000 668 | 110010011101 669 | 011110000011 670 | 111111110011 671 | 100001101100 672 | 000000011000 673 | 000100101101 674 | 000100110000 675 | 000110000010 676 | 011110010011 677 | 111001111111 678 | 000011110101 679 | 111001101100 680 | 111010111010 681 | 000101000101 682 | 111000010110 683 | 111010011000 684 | 101110100110 685 | 111100000100 686 | 101000110001 687 | 000001010110 688 | 101000100000 689 | 110111001010 690 | 001001101000 691 | 010011111010 692 | 100010100100 693 | 110010101001 694 | 111101100101 695 | 010001000101 696 | 011001111101 697 | 110000001110 698 | 100101101100 699 | 110110111100 700 | 010111011101 701 | 111011011100 702 | 011111011100 703 | 100100011001 704 | 111010011011 705 | 110011101011 706 | 100001101000 707 | 010110100010 708 | 101100100110 709 | 010110111010 710 | 111111011001 711 | 101011110011 712 | 011001101001 713 | 110011100111 714 | 010100111110 715 | 001001010011 716 | 010101110000 717 | 010111010101 718 | 100110011100 719 | 110010011011 720 | 001011010111 721 | 000001010100 722 | 001111011100 723 | 000010100100 724 | 010101011011 725 | 010100001011 726 | 000001011110 727 | 011111010111 728 | 010000101100 729 | 111111101111 730 | 100101010110 731 | 100011010101 732 | 100101100100 733 | 010011111101 734 | 010011001111 735 | 011010000101 736 | 110010000111 737 | 101110110110 738 | 000010001001 739 | 111000010010 740 | 111001001111 741 | 111000111010 742 | 010111011100 743 | 011010001101 744 | 111011011111 745 | 001010110001 746 | 011111111101 747 | 001001001011 748 | 100100011000 749 | 001000101010 750 | 101001111010 751 | 011101000010 752 | 111010000111 753 | 001000100000 754 | 100000100010 755 | 111111011000 756 | 110011000110 757 | 111111100010 758 | 100110011101 759 | 101111101000 760 | 001001001100 761 | 100001100001 762 | 100111110011 763 | 001000100010 764 | 011100011000 765 | 000001010010 766 | 100010111110 767 | 101111010010 768 | 100100000011 769 | 000101000010 770 | 101001011100 771 | 000101001101 772 | 000101110010 773 | 111111111011 774 | 110100000100 775 | 000001000010 776 | 101011010101 777 | 000011110011 778 | 000011001000 779 | 010111111001 780 | 111110100111 781 | 100110100111 782 | 001100001111 783 | 000100011110 784 | 001101000101 785 | 011110000000 786 | 000100111100 787 | 011110010111 788 | 011011010011 789 | 010101011110 790 | 100111001100 791 | 011111101010 792 | 011011001000 793 | 100100110100 794 | 011101010101 795 | 100101111001 796 | 100011101001 797 | 101010000001 798 | 101110111001 799 | 110100101111 800 | 010001001100 801 | 100110110000 802 | 100000111001 803 | 010111011011 804 | 111110001000 805 | 101000111101 806 | 000011010110 807 | 100010010010 808 | 010010011111 809 | 011110111110 810 | 000100111000 811 | 111100001101 812 | 000010110101 813 | 010010001110 814 | 101111000100 815 | 100101111100 816 | 010100011111 817 | 110101010010 818 | 000010111110 819 | 100001000100 820 | 001010001010 821 | 110000111100 822 | 010000101000 823 | 111000110110 824 | 001001101010 825 | 001101011100 826 | 001000001100 827 | 110010011100 828 | 011111000011 829 | 111100101101 830 | 110111010101 831 | 000010010110 832 | 111101110111 833 | 000011010010 834 | 111110000000 835 | 001111000101 836 | 100010111100 837 | 001011000011 838 | 010110000010 839 | 001101111101 840 | 101011000011 841 | 100001010010 842 | 100001010100 843 | 111100011101 844 | 010110001101 845 | 011101101101 846 | 101010101110 847 | 110111110100 848 | 001111001010 849 | 100010111101 850 | 011010001001 851 | 111111001000 852 | 100010100001 853 | 111010010110 854 | 001101000011 855 | 000011111011 856 | 110101000100 857 | 110101111101 858 | 010010000011 859 | 110101001111 860 | 001110111110 861 | 101111100011 862 | 011011011100 863 | 001100100100 864 | 010011111000 865 | 101010001111 866 | 111101010101 867 | 001110110001 868 | 101100010100 869 | 100010001000 870 | 101110000110 871 | 001101100001 872 | 111001000110 873 | 101110011110 874 | 100010000110 875 | 101010111011 876 | 001010110101 877 | 001101101110 878 | 100000101111 879 | 011001000001 880 | 010100001110 881 | 100111101000 882 | 011000110000 883 | 110000101111 884 | 010110111111 885 | 001110101000 886 | 111010100010 887 | 100000110100 888 | 100100000010 889 | 101010110011 890 | 010101000100 891 | 100100001011 892 | 000110011011 893 | 110001000010 894 | 111111000111 895 | 010001010010 896 | 001000011011 897 | 110010000101 898 | 111110110111 899 | 001000111001 900 | 101111100010 901 | 101001110010 902 | 001101101111 903 | 101001101101 904 | 001000010011 905 | 111000011111 906 | 111111110101 907 | 101001000001 908 | 010101101111 909 | 110100100100 910 | 001011101011 911 | 001010111100 912 | 000111100011 913 | 010001010100 914 | 110011000011 915 | 100111100000 916 | 001001111001 917 | 111111100001 918 | 001001100110 919 | 001000101001 920 | 111101011011 921 | 111000000010 922 | 100000100111 923 | 101011100100 924 | 001010111110 925 | 100110110100 926 | 110111100111 927 | 000110101000 928 | 011001000111 929 | 010111000001 930 | 101111101101 931 | 000001101101 932 | 000110100111 933 | 110001010100 934 | 111110101111 935 | 111110110101 936 | 111000010001 937 | 101111011010 938 | 101111110110 939 | 000000101100 940 | 010011010010 941 | 000101010101 942 | 100110101000 943 | 000111000011 944 | 001000010110 945 | 000111001010 946 | 000001000111 947 | 000101000110 948 | 000100010100 949 | 001011011101 950 | 001001111101 951 | 000000000101 952 | 000100100101 953 | 101010001101 954 | 001010000111 955 | 110110001110 956 | 000010011010 957 | 011001110101 958 | 111111101011 959 | 001100001100 960 | 100111001000 961 | 011010011000 962 | 000001101001 963 | 010001111001 964 | 001001110100 965 | 111110111000 966 | 000010010001 967 | 111111010011 968 | 100000011011 969 | 010110010100 970 | 010000111000 971 | 100001110110 972 | 111101111001 973 | 110000011010 974 | 100110101111 975 | 010001100111 976 | 100001011100 977 | 110000010011 978 | 010100001111 979 | 110010010110 980 | 110010111000 981 | 001011000110 982 | 101011001101 983 | 010000000100 984 | 010010000000 985 | 010100100101 986 | 110010100101 987 | 010101110110 988 | 101101001101 989 | 110000110011 990 | 110011110110 991 | 111101110110 992 | 001011111001 993 | 110101101000 994 | 101111111100 995 | 110011111101 996 | 100001111110 997 | 011101111000 998 | 101010000111 999 | 101110011111 1000 | 101000010101 -------------------------------------------------------------------------------- /day5/main.go: -------------------------------------------------------------------------------- 1 | package day5 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "runtime" 7 | "strconv" 8 | "strings" 9 | "sync" 10 | ) 11 | 12 | type point struct { 13 | x, y int64 14 | } 15 | 16 | type segment struct { 17 | x1, y1 int64 18 | x2, y2 int64 19 | 20 | // A linear function that this segment is part of. 21 | // y = ax + b, unless it's vertical line, then vertX is non MaxInt. 22 | a, b float64 23 | vertX int64 24 | } 25 | 26 | func newSegment(x1, y1, x2, y2 int64) segment { 27 | if x1 > x2 { 28 | x1, x2, y1, y2 = x2, x1, y2, y1 29 | } 30 | 31 | s := segment{ 32 | x1: x1, y1: y1, x2: x2, y2: y2, 33 | vertX: math.MaxInt, 34 | } 35 | 36 | if x2-x1 == 0 { 37 | // Vertical line. 38 | s.vertX = x2 39 | return s 40 | } 41 | 42 | // a * x1 + b = y1 43 | // a * x2 + b = y2 44 | // so: 45 | // b = y1 - a * x1 46 | // so: 47 | // a * x2 + y1 - a * x1 = y2 -> a (x2 - x1) = y2 - y1 -> a = (y2 - y1) / (x2 -x1) 48 | s.a = float64(y2-y1) / float64(x2-x1) 49 | s.b = float64(y1) - s.a*float64(x1) 50 | return s 51 | } 52 | 53 | func overlappedRange(a1, a2, b1, b2 int64) (s, e int64, potentialOverlap bool) { 54 | if a1 > a2 { 55 | a1, a2 = a2, a1 56 | } 57 | if b1 > b2 { 58 | b1, b2 = b2, b1 59 | } 60 | 61 | if a2 < b1 || b2 < a1 { 62 | return 0, 0, false 63 | } 64 | s = a1 65 | if s < b1 { 66 | s = b1 67 | } 68 | 69 | e = a2 70 | if e > b2 { 71 | e = b2 72 | } 73 | 74 | return s, e, true 75 | } 76 | 77 | func (l *segment) intersectionPoints(other *segment) (ret []point) { 78 | // Rough check of boundaries within "square". 79 | sx, ex, isOverlap := overlappedRange(l.x1, l.x2, other.x1, other.x2) 80 | if !isOverlap { 81 | return nil 82 | } 83 | sy, ey, isOverlap := overlappedRange(l.y1, l.y2, other.y1, other.y2) 84 | if !isOverlap { 85 | return nil 86 | } 87 | 88 | defer func() { 89 | for _, p := range ret { 90 | if p.x < sx || p.x > ex { 91 | panic("found point outside of x") 92 | } 93 | if p.y < sy || p.y > ey { 94 | panic("found point outside of y") 95 | } 96 | } 97 | }() 98 | 99 | if l.vertX != math.MaxInt { 100 | if other.vertX != math.MaxInt { 101 | if l.vertX != other.vertX { 102 | return nil 103 | } 104 | 105 | // Parallel, and same x. 106 | p := make([]point, 0, ey-sy) 107 | for i := sy; i <= ey; i++ { 108 | p = append(p, point{ 109 | x: l.vertX, 110 | y: i, 111 | }) 112 | } 113 | return p 114 | } 115 | y := int64(other.a*float64(l.vertX) + other.b) 116 | if y < sy || y > ey { 117 | return nil 118 | } 119 | return []point{{x: l.vertX, y: y}} 120 | } 121 | 122 | if other.vertX != math.MaxInt { 123 | y := int64(l.a*float64(other.vertX) + l.b) 124 | if y < sy || y > ey { 125 | return nil 126 | } 127 | return []point{{x: other.vertX, y: y}} 128 | } 129 | 130 | if l.a == other.a { 131 | // Parallel, but is b same? 132 | if l.b != other.b { 133 | // No intersect point. 134 | return nil 135 | } 136 | 137 | p := make([]point, 0, ex-sx) 138 | for i := sx; i <= ex; i++ { 139 | y := int64(l.a*float64(i) + l.b) 140 | if y < sy || y > ey { 141 | fmt.Println("outside!!") 142 | continue 143 | } 144 | 145 | p = append(p, point{x: i, y: y}) 146 | } 147 | return p 148 | } 149 | 150 | // a1 * x + b1 = y 151 | // a2 * x + b2 = y 152 | // so: 153 | // a1 * x + b1 = a2 * x + b2 -> x * (a1 - a2) = b2 - b1 -> x = (b2 - b1) / (a1 - a2) 154 | var p point 155 | xFloat := (other.b - l.b) / (l.a - other.a) 156 | if xFloat != math.Trunc(xFloat) { 157 | // Our space is discrete. 158 | return nil 159 | } 160 | p.x = int64(xFloat) 161 | p.y = int64(l.a*float64(p.x) + l.b) 162 | 163 | if p.x < sx || p.x > ex { 164 | return nil 165 | } 166 | if p.y < sy || p.y > ey { 167 | return nil 168 | } 169 | return []point{p} 170 | 171 | } 172 | 173 | func VentsOverlapPart1(input string) (_ int, err error) { 174 | var ( 175 | // TODO(bwplotka): Map can be quite large and slow, so idea could be to maintain sorted array 176 | // of overlaps by its distance from 0,0. 177 | overlaps = map[point]int{} 178 | segments = make([]segment, 0, 500) // 500 is "cheating" - I know max input size is 500. 179 | line string 180 | ) 181 | for len(input) > 0 { 182 | i := strings.IndexByte(input, '\n') 183 | if i == -1 { 184 | break 185 | } 186 | line = input[0:i] 187 | input = input[i+1:] 188 | 189 | s := strings.Split(line, " -> ") 190 | start := strings.Split(s[0], ",") 191 | end := strings.Split(s[1], ",") 192 | 193 | x1, err := strconv.ParseInt(start[0], 10, 64) 194 | if err != nil { 195 | return 0, err 196 | } 197 | y1, err := strconv.ParseInt(start[1], 10, 64) 198 | if err != nil { 199 | return 0, err 200 | } 201 | 202 | x2, err := strconv.ParseInt(end[0], 10, 64) 203 | if err != nil { 204 | return 0, err 205 | } 206 | y2, err := strconv.ParseInt(end[1], 10, 64) 207 | if err != nil { 208 | return 0, err 209 | } 210 | 211 | // Part1. 212 | if x1 != x2 && y1 != y2 { 213 | continue 214 | } 215 | 216 | newSeg := newSegment(x1, y1, x2, y2) 217 | 218 | fmt.Println("got", newSeg.x1, newSeg.y1, "->", newSeg.x2, newSeg.y2, newSeg.a, newSeg.b, newSeg.vertX) 219 | for _, seg := range segments { 220 | ps := seg.intersectionPoints(&newSeg) 221 | if len(ps) > 0 { 222 | fmt.Println("intersections against", seg.x1, seg.y1, "->", seg.x2, seg.y2, ps) 223 | } 224 | 225 | for _, p := range ps { 226 | overlaps[p]++ 227 | } 228 | } 229 | 230 | segments = append(segments, newSeg) 231 | } 232 | 233 | var numOverlaps int 234 | for _, o := range overlaps { 235 | if o > 0 { 236 | numOverlaps++ 237 | } 238 | } 239 | 240 | return numOverlaps, nil 241 | } 242 | 243 | func VentsOverlapPart2(input string) (_ int, err error) { 244 | var ( 245 | // TODO(bwplotka): Map can be quite large and slow, so idea could be to maintain sorted array 246 | // of overlaps by its distance from 0,0. 247 | overlaps = map[point]int{} 248 | segments = make([]segment, 0, 500) // 500 is "cheating" - I know max input size is 500. 249 | line string 250 | ) 251 | for len(input) > 0 { 252 | i := strings.IndexByte(input, '\n') 253 | if i == -1 { 254 | break 255 | } 256 | line = input[0:i] 257 | input = input[i+1:] 258 | 259 | s := strings.Split(line, " -> ") 260 | start := strings.Split(s[0], ",") 261 | end := strings.Split(s[1], ",") 262 | 263 | x1, err := strconv.ParseInt(start[0], 10, 64) 264 | if err != nil { 265 | return 0, err 266 | } 267 | y1, err := strconv.ParseInt(start[1], 10, 64) 268 | if err != nil { 269 | return 0, err 270 | } 271 | 272 | x2, err := strconv.ParseInt(end[0], 10, 64) 273 | if err != nil { 274 | return 0, err 275 | } 276 | y2, err := strconv.ParseInt(end[1], 10, 64) 277 | if err != nil { 278 | return 0, err 279 | } 280 | 281 | newSeg := newSegment(x1, y1, x2, y2) 282 | 283 | // Useful debug log (: 284 | // fmt.Println("got", newSeg.x1, newSeg.y1, "->", newSeg.x2, newSeg.y2, newSeg.a, newSeg.b, newSeg.vertX) 285 | for _, seg := range segments { 286 | ps := seg.intersectionPoints(&newSeg) 287 | // Useful debug log. 288 | //if len(ps) > 0 { 289 | // fmt.Println("intersections against", seg.x1, seg.y1, "->", seg.x2, seg.y2, ps) 290 | //} 291 | 292 | for _, p := range ps { 293 | overlaps[p]++ 294 | } 295 | } 296 | 297 | segments = append(segments, newSeg) 298 | } 299 | 300 | var numOverlaps int 301 | for _, o := range overlaps { 302 | if o > 0 { 303 | numOverlaps++ 304 | } 305 | } 306 | 307 | return numOverlaps, nil 308 | } 309 | 310 | // VentsOverlapPart2_V2 is optimized version of VentsOverlapPart2. 311 | // Main offendant are intersection functions as well as mapassign (as we predicted). 312 | // For space it's mainly []points and splits while parsing. 313 | func VentsOverlapPart2_V2(input string) (_ int, err error) { 314 | var ( 315 | // TODO(bwplotka): Map can be quite large and slow, so idea could be to maintain sorted array 316 | // of overlaps by its distance from 0,0. 317 | overlaps = make(map[point]struct{}, 500) 318 | segments = make([]segment_V2, 0, 500) // 500 is "cheating" - I know max input size is 500. 319 | line string 320 | ) 321 | for len(input) > 0 { 322 | i := strings.IndexByte(input, '\n') 323 | if i == -1 { 324 | break 325 | } 326 | line = input[0:i] 327 | input = input[i+1:] 328 | 329 | s := strings.Split(line, " -> ") 330 | start := strings.Split(s[0], ",") 331 | end := strings.Split(s[1], ",") 332 | 333 | x1, err := strconv.ParseInt(start[0], 10, 64) 334 | if err != nil { 335 | return 0, err 336 | } 337 | y1, err := strconv.ParseInt(start[1], 10, 64) 338 | if err != nil { 339 | return 0, err 340 | } 341 | 342 | x2, err := strconv.ParseInt(end[0], 10, 64) 343 | if err != nil { 344 | return 0, err 345 | } 346 | y2, err := strconv.ParseInt(end[1], 10, 64) 347 | if err != nil { 348 | return 0, err 349 | } 350 | 351 | newSeg := newSegment_V2(x1, y1, x2, y2) 352 | 353 | var p point 354 | markFn := func(x, y int64) { 355 | p.x = x 356 | p.y = y 357 | if _, ok := overlaps[p]; !ok { 358 | overlaps[p] = struct{}{} 359 | } 360 | } 361 | for _, seg := range segments { 362 | seg.markIntersectionPoints(&newSeg, markFn) 363 | } 364 | 365 | segments = append(segments, newSeg) 366 | } 367 | 368 | return len(overlaps), nil 369 | } 370 | 371 | type segment_V2 struct { 372 | x1, y1 int64 373 | x2, y2 int64 374 | 375 | // A linear function that this segment is part of. 376 | // y = ax + b, unless it's vertical line, then vertX is non MaxInt. 377 | a, b float64 378 | vertX int64 379 | } 380 | 381 | func newSegment_V2(x1, y1, x2, y2 int64) segment_V2 { 382 | if x1 > x2 { 383 | x1, x2, y1, y2 = x2, x1, y2, y1 384 | } 385 | 386 | s := segment_V2{ 387 | x1: x1, y1: y1, x2: x2, y2: y2, 388 | vertX: math.MaxInt, 389 | } 390 | 391 | if x2-x1 == 0 { 392 | // Vertical line. 393 | s.vertX = x2 394 | return s 395 | } 396 | 397 | // a * x1 + b = y1 398 | // a * x2 + b = y2 399 | // so: 400 | // b = y1 - a * x1 401 | // so: 402 | // a * x2 + y1 - a * x1 = y2 -> a (x2 - x1) = y2 - y1 -> a = (y2 - y1) / (x2 -x1) 403 | s.a = float64(y2-y1) / float64(x2-x1) 404 | s.b = float64(y1) - s.a*float64(x1) 405 | return s 406 | } 407 | 408 | func overlappedRange_V2(a1, a2, b1, b2 int64) (s, e int64, potentialOverlap bool) { 409 | if a1 > a2 { 410 | a1, a2 = a2, a1 411 | } 412 | if b1 > b2 { 413 | b1, b2 = b2, b1 414 | } 415 | 416 | if a2 < b1 || b2 < a1 { 417 | return 0, 0, false 418 | } 419 | s = a1 420 | if s < b1 { 421 | s = b1 422 | } 423 | 424 | e = a2 425 | if e > b2 { 426 | e = b2 427 | } 428 | 429 | return s, e, true 430 | } 431 | 432 | func (l *segment_V2) markIntersectionPoints(other *segment_V2, markFn func(x, y int64)) { 433 | // Rough check of boundaries within "square". 434 | sx, ex, isOverlap := overlappedRange_V2(l.x1, l.x2, other.x1, other.x2) 435 | if !isOverlap { 436 | return 437 | } 438 | sy, ey, isOverlap := overlappedRange_V2(l.y1, l.y2, other.y1, other.y2) 439 | if !isOverlap { 440 | return 441 | } 442 | 443 | if l.vertX != math.MaxInt { 444 | if other.vertX != math.MaxInt { 445 | if l.vertX != other.vertX { 446 | return 447 | } 448 | 449 | // Parallel, and same x. 450 | for i := sy; i <= ey; i++ { 451 | markFn(l.vertX, i) 452 | } 453 | return 454 | } 455 | y := int64(other.a*float64(l.vertX) + other.b) 456 | if y < sy || y > ey { 457 | return 458 | } 459 | markFn(l.vertX, y) 460 | return 461 | } 462 | 463 | if other.vertX != math.MaxInt { 464 | y := int64(l.a*float64(other.vertX) + l.b) 465 | if y < sy || y > ey { 466 | return 467 | } 468 | markFn(other.vertX, y) 469 | return 470 | } 471 | 472 | if l.a == other.a { 473 | // Parallel, but is b same? 474 | if l.b != other.b { 475 | // No intersect point. 476 | return 477 | } 478 | 479 | for i := sx; i <= ex; i++ { 480 | y := int64(l.a*float64(i) + l.b) 481 | if y < sy || y > ey { 482 | continue 483 | } 484 | 485 | markFn(i, y) 486 | } 487 | return 488 | } 489 | 490 | // a1 * x + b1 = y 491 | // a2 * x + b2 = y 492 | // so: 493 | // a1 * x + b1 = a2 * x + b2 -> x * (a1 - a2) = b2 - b1 -> x = (b2 - b1) / (a1 - a2) 494 | xFloat := (other.b - l.b) / (l.a - other.a) 495 | if xFloat != math.Trunc(xFloat) { 496 | // Our space is discrete. 497 | return 498 | } 499 | x := int64(xFloat) 500 | y := int64(l.a*float64(x) + l.b) 501 | 502 | if x < sx || x > ex || y < sy || y > ey { 503 | return 504 | } 505 | markFn(x, y) 506 | } 507 | 508 | // VentsOverlapPart2_V3 is optimized version of VentsOverlapPart2_V2. 509 | // Main offendant is still intersection functions as well as mapassign (as we predicted). 510 | // For space it's mainly splits while parsing. 511 | func VentsOverlapPart2_V3(input string) (_ int, err error) { 512 | var ( 513 | // Map can be quite large and slow, so idea could be to maintain an array of 1000*1000 elements. 514 | // That's 1MB, which we need to live with (: Trade-off to win latency. 515 | overlaps = make([]bool, 1000*1000) 516 | newOverlaps int 517 | 518 | segments = make([]segment_V2, 0, 500) // 500 is "cheating" - I know max input size is 500. 519 | line string 520 | ) 521 | for len(input) > 0 { 522 | i := strings.IndexByte(input, '\n') 523 | if i == -1 { 524 | break 525 | } 526 | line = input[0:i] 527 | input = input[i+1:] 528 | 529 | s := strings.Split(line, " -> ") 530 | start := strings.Split(s[0], ",") 531 | end := strings.Split(s[1], ",") 532 | 533 | x1, err := strconv.ParseInt(start[0], 10, 64) 534 | if err != nil { 535 | return 0, err 536 | } 537 | y1, err := strconv.ParseInt(start[1], 10, 64) 538 | if err != nil { 539 | return 0, err 540 | } 541 | 542 | x2, err := strconv.ParseInt(end[0], 10, 64) 543 | if err != nil { 544 | return 0, err 545 | } 546 | y2, err := strconv.ParseInt(end[1], 10, 64) 547 | if err != nil { 548 | return 0, err 549 | } 550 | 551 | newSeg := newSegment_V2(x1, y1, x2, y2) 552 | 553 | markFn := func(x, y int64) { 554 | i := x + 1000*y 555 | if overlaps[i] { 556 | return 557 | } 558 | overlaps[i] = true 559 | 560 | newOverlaps++ 561 | } 562 | for _, seg := range segments { 563 | seg.markIntersectionPoints(&newSeg, markFn) 564 | } 565 | 566 | segments = append(segments, newSeg) 567 | } 568 | 569 | return newOverlaps, nil 570 | } 571 | 572 | // VentsOverlapPart2_V4 is optimized version of VentsOverlapPart2_V3. 573 | // Main offendant is still intersection functions and 6% split. 574 | func VentsOverlapPart2_V4(input string) (_ int, err error) { 575 | var ( 576 | // Map can be quite large and slow, so idea could be to maintain an array of 1000*1000 elements. 577 | // That's 1MB, which we need to live with (: Trade-off to win latency. 578 | overlaps = make([]bool, 1000*1000) 579 | newOverlaps int 580 | 581 | segments = make([]segment_V2, 0, 500) // 500 is "cheating" - I know max input size is 500. 582 | ) 583 | 584 | for i := 0; i < len(input); { 585 | j := i 586 | for input[i] != ',' { 587 | i++ 588 | } 589 | x1, err := strconv.ParseInt(input[j:i], 10, 64) 590 | if err != nil { 591 | return 0, err 592 | } 593 | 594 | i++ 595 | j = i 596 | for input[i] != ' ' { 597 | i++ 598 | } 599 | y1, err := strconv.ParseInt(input[j:i], 10, 64) 600 | if err != nil { 601 | return 0, err 602 | } 603 | 604 | i += 4 605 | j = i 606 | for input[i] != ',' { 607 | i++ 608 | } 609 | x2, err := strconv.ParseInt(input[j:i], 10, 64) 610 | if err != nil { 611 | return 0, err 612 | } 613 | 614 | i++ 615 | j = i 616 | for input[i] != '\n' { 617 | i++ 618 | } 619 | y2, err := strconv.ParseInt(input[j:i], 10, 64) 620 | if err != nil { 621 | return 0, err 622 | } 623 | i++ 624 | 625 | newSeg := newSegment_V2(x1, y1, x2, y2) 626 | markFn := func(x, y int64) { 627 | i := x + 1000*y 628 | if overlaps[i] { 629 | return 630 | } 631 | overlaps[i] = true 632 | newOverlaps++ 633 | } 634 | for _, seg := range segments { 635 | seg.markIntersectionPoints(&newSeg, markFn) 636 | } 637 | 638 | segments = append(segments, newSeg) 639 | } 640 | 641 | return newOverlaps, nil 642 | } 643 | 644 | const shardBy = 250 645 | 646 | // VentsOverlapPart2_V5 is optimized version of VentsOverlapPart2_V4 647 | // Main offendant is still intersection functions. 648 | // NOTE: Spliting into 4 shards only increases intersection calls 124750 in v4 vs 126092, but we can do them concurrently! 649 | func VentsOverlapPart2_V5(input string) (_ int, err error) { 650 | runtime.GOMAXPROCS(4) 651 | 652 | var ( 653 | // Map can be quite large and slow, so idea could be to maintain an array of 1000*1000 elements. 654 | // That's 1MB, which we need to live with (: Trade-off to win latency. 655 | overlaps = make([]bool, 1000*1000) 656 | 657 | // Let's shard x space per 250 points (4 shards for input) so n*n-1 space is smaller too. 658 | // Overlaps don't need to be sharded - since separate positions should be always accessed per shard. 659 | newOverlaps = make([]int, 4) 660 | markFns = make([]func(x, y int64), 4) 661 | segments = make([][]segment_V2, 4) 662 | ) 663 | 664 | for k := 0; k < 4; k++ { 665 | segments[k] = make([]segment_V2, 0, 300) // 500 is "cheating" - I know max input size is 500. 666 | k := k 667 | markFns[k] = func(x, y int64) { 668 | i := x + 1000*y 669 | if overlaps[i] { 670 | return 671 | } 672 | overlaps[i] = true 673 | newOverlaps[k]++ 674 | } 675 | } 676 | 677 | for i := 0; i < len(input); { 678 | j := i 679 | for input[i] != ',' { 680 | i++ 681 | } 682 | x1, err := strconv.ParseInt(input[j:i], 10, 64) 683 | if err != nil { 684 | return 0, err 685 | } 686 | 687 | i++ 688 | j = i 689 | for input[i] != ' ' { 690 | i++ 691 | } 692 | y1, err := strconv.ParseInt(input[j:i], 10, 64) 693 | if err != nil { 694 | return 0, err 695 | } 696 | 697 | i += 4 698 | j = i 699 | for input[i] != ',' { 700 | i++ 701 | } 702 | x2, err := strconv.ParseInt(input[j:i], 10, 64) 703 | if err != nil { 704 | return 0, err 705 | } 706 | 707 | i++ 708 | j = i 709 | for input[i] != '\n' { 710 | i++ 711 | } 712 | y2, err := strconv.ParseInt(input[j:i], 10, 64) 713 | if err != nil { 714 | return 0, err 715 | } 716 | i++ 717 | 718 | newSeg := newSegment_V2(x1, y1, x2, y2) 719 | 720 | shard := newSeg.x1 / shardBy 721 | shard2 := newSeg.x2 / shardBy 722 | 723 | for k := shard; k <= shard2; k++ { 724 | seg := newSeg 725 | if k < shard2 { 726 | 727 | // Note, vertical line impossible, so we can exclude. 728 | seg = segment_V2{ 729 | x1: newSeg.x1, y1: newSeg.y1, 730 | a: newSeg.a, b: newSeg.b, 731 | vertX: math.MaxInt, 732 | } 733 | 734 | seg.x2 = (k+1)*shardBy - 1 735 | seg.y2 = int64(newSeg.a*float64(seg.x2) + newSeg.b) 736 | newSeg.x1 = seg.x2 + 1 737 | newSeg.y1 = int64(newSeg.a*float64(newSeg.x1) + newSeg.b) 738 | } 739 | 740 | segments[k] = append(segments[k], seg) 741 | } 742 | } 743 | 744 | wg := sync.WaitGroup{} 745 | for s, parts := range segments { 746 | wg.Add(1) 747 | parts := parts 748 | s := s 749 | go func() { 750 | defer wg.Done() 751 | for i, p := range parts { 752 | for _, other := range parts[i+1:] { 753 | other.markIntersectionPoints(&p, markFns[s]) 754 | } 755 | } 756 | }() 757 | } 758 | wg.Wait() 759 | 760 | return newOverlaps[0] + newOverlaps[1] + newOverlaps[2] + newOverlaps[3], nil 761 | } 762 | --------------------------------------------------------------------------------