adventofcode/day11/main2.go

111 lines
2.0 KiB
Go

package main
import (
"fmt"
"io/ioutil"
"strings"
)
type Grid [][]rune
func surrounding(gr *Grid, row, col int) int {
counts := 0
for i := -1; i <= 1; i++ {
for j := -1; j <= 1; j++ {
if !(i == 0 && j == 0) { // don't check the current tile
if occupied(gr, row, col, i, j) {
counts += 1
}
}
}
}
return counts
}
// unlike the part 1 version, this version of occupied searches outside the immediate neighborhood
func occupied(gr *Grid, row, col, rstep, cstep int) bool {
g := *gr
r := row
c := col
done := false
for !done {
r += rstep
c += cstep
if r < 0 || r+1 > len(g) || c < 0 || c+1 > len(g[0]) {
return false
} else if g[r][c] == '#' {
return true
} else if g[r][c] == 'L' {
return false
}
}
return false
}
func printgrid(gr *Grid) {
for _, r := range *gr {
for _, c := range r {
fmt.Printf("%c", c)
}
fmt.Printf("\n")
}
fmt.Printf("\n")
}
func main() {
d, _ := ioutil.ReadFile("input")
lines := strings.Split(string(d), "\n")
var grid Grid
for _, l := range lines {
if l != "" {
var gridline []rune
for _, c := range l {
gridline = append(gridline, c)
}
grid = append(grid, gridline)
}
}
generations := 0
seats := 0 // number of occupied seats
stable := false
for !stable {
seats = 0
var newgrid Grid
for row, i := range grid {
var r []rune
for col, char := range i {
if char == '.' {
r = append(r, '.') // floor, floor never changes
} else {
s := surrounding(&grid, row, col)
if char == 'L' && s == 0 {
r = append(r, '#')
} else if char == '#' && s >= 5 {
r = append(r, 'L')
} else {
r = append(r, char)
}
}
}
newgrid = append(newgrid, r)
}
// printgrid(&newgrid)
generations += 1
stable = true
for i, r := range grid {
for j, _ := range r {
if grid[i][j] != newgrid[i][j] {
stable = false
}
if newgrid[i][j] == '#' {
seats += 1
}
}
}
grid = newgrid
}
fmt.Println("Generations until stability:", generations)
fmt.Println("Occupied Seats:", seats)
}