aoc2020/day11/lib.go

95 lines
1.8 KiB
Go

package day11
type Coordinate struct {
X, Y int
}
func GetNearbySeatStatus(coord Coordinate, checkOnlyNearby bool) int {
occupied := 0
for x := -1; x <= 1; x++ {
for y := -1; y <= 1; y++ {
if x == 0 && y == 0 {
continue
}
isOccupied := CheckSeatDirection(
coord,
Coordinate{X: x, Y: y},
checkOnlyNearby,
)
if isOccupied {
occupied++
}
}
}
return occupied
}
func CheckSeatDirection(coord Coordinate, dir Coordinate, checkOnlyNearby bool) bool {
adjCoord := Coordinate{X: coord.X + dir.X, Y: coord.Y + dir.Y}
// If out of bounds, it's not occupied and we can't check furter
if rows[adjCoord] == "" {
return false
}
// If we only should check one step, just check that one step
if checkOnlyNearby {
return rows[adjCoord] == "#"
}
// If it's a floor tile, recurse further
if rows[adjCoord] == "." {
return CheckSeatDirection(adjCoord, dir, checkOnlyNearby)
}
return rows[adjCoord] == "#"
}
func MakeSeatChanges(tolerance int, checkOnlyNearby bool) int {
changes := make(map[Coordinate]string)
// Calculate changes
for coord, status := range rows {
// Ignore floor tiles
if status == "." {
continue
}
// Get nearby seat statuses
occupiedCount := GetNearbySeatStatus(coord, checkOnlyNearby)
// If current seat is free, check that there's nobody around
if status == "L" && occupiedCount == 0 {
changes[coord] = "#"
}
// If the current seat isn't free, check how many people there's around
if status == "#" && occupiedCount >= tolerance {
changes[coord] = "L"
}
}
// Apply changes
for coord, change := range changes {
rows[coord] = change
}
return len(changes)
}
func CountOccupiedSeats() int {
counter := 0
for _, status := range rows {
if status == "#" {
counter++
}
}
return counter
}