LeetCode/go/rotting-oranges.go

80 lines
1.3 KiB
Go
Raw Normal View History

package main
import (
aq "github.com/emirpasic/gods/v2/queues/arrayqueue"
)
const (
EMPTY_CELL int = 0
FRESH_ORANGE int = 1
ROTTEN_ORANGE int = 2
)
type BFSEntry struct {
time int
y, x int
}
func orangesRotting(grid [][]int) int {
DIRECTIONS := [][]int{
[]int{0, 1},
[]int{0, -1},
[]int{1, 0},
[]int{-1, 0},
}
inBounds := func(y, x int) bool {
return y >= 0 && y < len(grid) && x >= 0 && x < len(grid[y])
}
countFresh := func() int {
fresh := 0
for _, row := range grid {
for _, orange := range row {
if orange == FRESH_ORANGE {
fresh++
}
}
}
return fresh
}
initializeQueue := func(q *aq.Queue[BFSEntry]) {
for y, row := range grid {
for x, orange := range row {
if orange != ROTTEN_ORANGE {
continue
}
q.Enqueue(BFSEntry{time: 0, y: y, x: x})
}
}
}
q := aq.New[BFSEntry]()
initializeQueue(q)
fresh, time := countFresh(), 0
for !q.Empty() && fresh > 0 {
value, _ := q.Dequeue()
for _, d := range DIRECTIONS {
ny, nx := value.y+d[0], value.x+d[1]
if !inBounds(ny, nx) || grid[ny][nx] != FRESH_ORANGE {
continue
}
grid[ny][nx] = ROTTEN_ORANGE
fresh--
q.Enqueue(BFSEntry{time: value.time + 1, y: ny, x: nx})
time = value.time + 1
}
}
if fresh > 0 {
return -1
}
return time
}