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 }