You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
254 lines
5.6 KiB
Go
254 lines
5.6 KiB
Go
package day21
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils"
|
|
)
|
|
|
|
type Coord struct {
|
|
row int
|
|
col int
|
|
}
|
|
|
|
func BFS1(matrix [][]byte, root Coord, maxSteps int) int {
|
|
height := len(matrix)
|
|
width := len(matrix[0])
|
|
queue := utils.NewQueue[*Coord]()
|
|
|
|
matrix[root.row][root.col] = 'O'
|
|
queue.Enqueue(&root)
|
|
|
|
moves := 0
|
|
for moves < maxSteps {
|
|
//fmt.Println(moves + 1)
|
|
newQueue := utils.NewQueue[*Coord]()
|
|
|
|
for queue.HasElement() {
|
|
coord := queue.Dequeue()
|
|
matrix[coord.row][coord.col] = '.'
|
|
|
|
if coord.row > 0 && matrix[coord.row-1][coord.col] != '#' {
|
|
newCoord := Coord{coord.row - 1, coord.col}
|
|
newQueue.Enqueue(&newCoord)
|
|
matrix[newCoord.row][newCoord.col] = 'O'
|
|
}
|
|
|
|
if coord.row < height-1 && matrix[coord.row+1][coord.col] != '#' {
|
|
newCoord := Coord{coord.row + 1, coord.col}
|
|
newQueue.Enqueue(&newCoord)
|
|
matrix[newCoord.row][newCoord.col] = 'O'
|
|
}
|
|
|
|
if coord.col > 0 && matrix[coord.row][coord.col-1] != '#' {
|
|
newCoord := Coord{coord.row, coord.col - 1}
|
|
newQueue.Enqueue(&newCoord)
|
|
matrix[newCoord.row][newCoord.col] = 'O'
|
|
}
|
|
|
|
if coord.col < width-1 && matrix[coord.row][coord.col+1] != '#' {
|
|
newCoord := Coord{coord.row, coord.col + 1}
|
|
newQueue.Enqueue(&newCoord)
|
|
matrix[newCoord.row][newCoord.col] = 'O'
|
|
}
|
|
}
|
|
|
|
queue = newQueue
|
|
moves++
|
|
}
|
|
|
|
// count 'O' in matrix
|
|
count := 0
|
|
for r := range matrix {
|
|
for _, b := range matrix[r] {
|
|
if b == 'O' {
|
|
count++
|
|
}
|
|
}
|
|
}
|
|
|
|
return count
|
|
}
|
|
|
|
func redrawFromCache(matrix [][]byte, cacheQueue utils.Queue[*Coord]) {
|
|
for _, coord := range cacheQueue.GetData() {
|
|
if coord != nil {
|
|
matrix[coord.row][coord.col] = 'O'
|
|
}
|
|
}
|
|
}
|
|
|
|
func BFS2(matrix [][]byte, root Coord, maxSteps int) int {
|
|
height := len(matrix)
|
|
width := len(matrix[0])
|
|
queue := utils.NewQueue[*Coord]()
|
|
|
|
cache := make([][]utils.Queue[*Coord], height)
|
|
for r, row := range matrix {
|
|
cache[r] = make([]utils.Queue[*Coord], width)
|
|
for c := range row {
|
|
cache[r][c] = utils.NewQueue[*Coord]()
|
|
}
|
|
}
|
|
|
|
matrix[root.row][root.col] = 'O'
|
|
queue.Enqueue(&root)
|
|
|
|
moves := 0
|
|
for moves < maxSteps {
|
|
fmt.Println(moves + 1)
|
|
newQueue := utils.NewQueue[*Coord]()
|
|
|
|
for queue.HasElement() {
|
|
coord := queue.Dequeue()
|
|
|
|
if cache[coord.row][coord.col].HasElement() {
|
|
|
|
matrix[coord.row][coord.col] = '.'
|
|
redrawFromCache(matrix, cache[coord.row][coord.col])
|
|
|
|
} else {
|
|
cacheQueue := utils.NewQueue[*Coord]()
|
|
matrix[coord.row][coord.col] = '.'
|
|
|
|
if coord.row > 0 && matrix[coord.row-1][coord.col] != '#' {
|
|
newCoord := Coord{coord.row - 1, coord.col}
|
|
newQueue.Enqueue(&newCoord)
|
|
matrix[newCoord.row][newCoord.col] = 'O'
|
|
cacheQueue.Enqueue(&newCoord)
|
|
}
|
|
|
|
if coord.row < height-1 && matrix[coord.row+1][coord.col] != '#' {
|
|
newCoord := Coord{coord.row + 1, coord.col}
|
|
newQueue.Enqueue(&newCoord)
|
|
matrix[newCoord.row][newCoord.col] = 'O'
|
|
cacheQueue.Enqueue(&newCoord)
|
|
}
|
|
|
|
if coord.col > 0 && matrix[coord.row][coord.col-1] != '#' {
|
|
newCoord := Coord{coord.row, coord.col - 1}
|
|
newQueue.Enqueue(&newCoord)
|
|
matrix[newCoord.row][newCoord.col] = 'O'
|
|
cacheQueue.Enqueue(&newCoord)
|
|
}
|
|
|
|
if coord.col < width-1 && matrix[coord.row][coord.col+1] != '#' {
|
|
newCoord := Coord{coord.row, coord.col + 1}
|
|
newQueue.Enqueue(&newCoord)
|
|
matrix[newCoord.row][newCoord.col] = 'O'
|
|
cacheQueue.Enqueue(&newCoord)
|
|
}
|
|
|
|
cache[coord.row][coord.col] = cacheQueue
|
|
}
|
|
}
|
|
|
|
queue = newQueue
|
|
moves++
|
|
}
|
|
|
|
// count 'O' in matrix
|
|
count := 0
|
|
for r := range matrix {
|
|
for _, b := range matrix[r] {
|
|
if b == 'O' {
|
|
count++
|
|
}
|
|
}
|
|
}
|
|
|
|
return count
|
|
}
|
|
|
|
func BFS3(matrix [][]byte, root Coord, maxSteps int) int {
|
|
height := len(matrix)
|
|
width := len(matrix[0])
|
|
queue := utils.NewQueue[*Coord]()
|
|
|
|
matrix[root.row][root.col] = 'O'
|
|
queue.Enqueue(&root)
|
|
|
|
moves := 0
|
|
for moves < maxSteps {
|
|
//fmt.Println(moves + 1)
|
|
newQueue := utils.NewQueue[*Coord]()
|
|
coordInQueue := map[Coord]bool{}
|
|
|
|
for queue.HasElement() {
|
|
coord := queue.Dequeue()
|
|
matrix[coord.row][coord.col] = '.'
|
|
|
|
if coord.row > 0 && matrix[coord.row-1][coord.col] != '#' {
|
|
newCoord := Coord{coord.row - 1, coord.col}
|
|
if !coordInQueue[newCoord] {
|
|
newQueue.Enqueue(&newCoord)
|
|
matrix[newCoord.row][newCoord.col] = 'O'
|
|
coordInQueue[newCoord] = true
|
|
}
|
|
}
|
|
|
|
if coord.row < height-1 && matrix[coord.row+1][coord.col] != '#' {
|
|
newCoord := Coord{coord.row + 1, coord.col}
|
|
if !coordInQueue[newCoord] {
|
|
newQueue.Enqueue(&newCoord)
|
|
matrix[newCoord.row][newCoord.col] = 'O'
|
|
coordInQueue[newCoord] = true
|
|
}
|
|
}
|
|
|
|
if coord.col > 0 && matrix[coord.row][coord.col-1] != '#' {
|
|
newCoord := Coord{coord.row, coord.col - 1}
|
|
if !coordInQueue[newCoord] {
|
|
newQueue.Enqueue(&newCoord)
|
|
matrix[newCoord.row][newCoord.col] = 'O'
|
|
coordInQueue[newCoord] = true
|
|
}
|
|
}
|
|
|
|
if coord.col < width-1 && matrix[coord.row][coord.col+1] != '#' {
|
|
newCoord := Coord{coord.row, coord.col + 1}
|
|
if !coordInQueue[newCoord] {
|
|
newQueue.Enqueue(&newCoord)
|
|
matrix[newCoord.row][newCoord.col] = 'O'
|
|
coordInQueue[newCoord] = true
|
|
}
|
|
}
|
|
}
|
|
|
|
queue = newQueue
|
|
moves++
|
|
}
|
|
|
|
// count 'O' in matrix
|
|
count := 0
|
|
for r := range matrix {
|
|
for _, b := range matrix[r] {
|
|
if b == 'O' {
|
|
count++
|
|
}
|
|
}
|
|
}
|
|
|
|
return count
|
|
}
|
|
|
|
func Part1(lines []string, maxSteps int) int {
|
|
matrix := make([][]byte, len(lines))
|
|
|
|
var root Coord
|
|
for r, line := range lines {
|
|
matrix[r] = make([]byte, len(line))
|
|
for c, b := range line {
|
|
matrix[r][c] = byte(b)
|
|
if b == 'S' {
|
|
root.row = r
|
|
root.col = c
|
|
}
|
|
}
|
|
}
|
|
|
|
result := BFS3(matrix, root, maxSteps)
|
|
|
|
return result
|
|
}
|