mirror of
https://github.com/Threnklyn/advent-of-code-go.git
synced 2026-05-31 09:18:27 +02:00
88 lines
1.7 KiB
Go
88 lines
1.7 KiB
Go
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
|
|
}
|