2016-day13: bfs a grid with some extra math equation

This commit is contained in:
alexchao26
2020-12-23 21:01:28 -05:00
parent 0c00fc6cba
commit 64c9b6d466
2 changed files with 118 additions and 0 deletions
+87
View File
@@ -0,0 +1,87 @@
package main
import (
"flag"
"fmt"
"github.com/alexchao26/advent-of-code-go/cast"
"github.com/alexchao26/advent-of-code-go/util"
)
func main() {
var part int
flag.IntVar(&part, "part", 1, "part 1 or 2")
flag.Parse()
fmt.Println("Running part", part)
ans := bfs(util.ReadFile("./input.txt"), [2]int{31, 39}, part)
fmt.Println("Output:", ans)
}
var dirs = [][2]int{
{-1, 0},
{1, 0},
{0, 1},
{0, -1},
}
func bfs(input string, destination [2]int, part int) int {
inputNum := cast.ToInt(input)
// bfs queue
queue := [][3]int{[3]int{1, 1, 0}} // x,y, DIST
// to not re-visit cells
visited := map[[2]int]bool{}
// for part 2
uniqueVisitsUnder50 := map[[2]int]bool{}
for len(queue) > 0 {
front := queue[0]
queue = queue[1:]
currentX, currentY := front[0], front[1]
currentDist := front[2]
// part 1 return
if part == 1 && currentX == destination[0] && currentY == destination[1] {
return currentDist
}
// if already visited, skip
if !visited[[2]int{currentX, currentY}] {
// for part 2, check if distance is 50 or less
if currentDist <= 50 {
uniqueVisitsUnder50[[2]int{currentX, currentY}] = true
}
if part == 2 && currentDist > 50 {
break
}
for _, diff := range dirs {
nextX, nextY := currentX+diff[0], currentY+diff[1]
if nextX >= 0 && nextY >= 0 {
if isOpenSpace(nextX, nextY, inputNum) {
queue = append(queue, [3]int{nextX, nextY, currentDist + 1})
}
}
}
}
visited[[2]int{currentX, currentY}] = true
}
return len(uniqueVisitsUnder50)
}
func isOpenSpace(x, y, inputNum int) bool {
num := x*x + 3*x + 2*x*y + y + y*y + inputNum
binStr := fmt.Sprintf("%b", num)
var ones int
for _, char := range binStr {
if char == '1' {
ones++
}
}
return ones%2 == 0
}
+31
View File
@@ -0,0 +1,31 @@
package main
import (
"testing"
"github.com/alexchao26/advent-of-code-go/util"
)
func Test_bfs(t *testing.T) {
type args struct {
input string
destination [2]int
part int
}
tests := []struct {
name string
args args
want int
}{
{"example", args{"10", [2]int{7, 4}, 1}, 11},
{"actual_part1", args{util.ReadFile("input.txt"), [2]int{31, 39}, 1}, 86},
{"actual_part2", args{util.ReadFile("input.txt"), [2]int{31, 39}, 2}, 127},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := bfs(tt.args.input, tt.args.destination, tt.args.part); got != tt.want {
t.Errorf("bfs() = %v, want %v", got, tt.want)
}
})
}
}