91 lines
2.0 KiB
Go
91 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"strings"
|
|
)
|
|
|
|
var rows, cols int // extent of input configuration
|
|
var rx, cx int // grid extent (includes border)
|
|
var mn []int // offsets of moore neighborhood
|
|
|
|
func main() {
|
|
// read input configuration from file
|
|
src, err := ioutil.ReadFile("ww.config")
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
srcRows := bytes.Split(src, []byte{'\n'})
|
|
|
|
// compute package variables
|
|
rows = len(srcRows)
|
|
for _, r := range srcRows {
|
|
if len(r) > cols {
|
|
cols = len(r)
|
|
}
|
|
}
|
|
rx, cx = rows+2, cols+2
|
|
mn = []int{-cx-1, -cx, -cx+1, -1, 1, cx-1, cx, cx+1}
|
|
|
|
// allocate two grids and copy input into first grid
|
|
odd := make([]byte, rx*cx)
|
|
even := make([]byte, rx*cx)
|
|
for ri, r := range srcRows {
|
|
copy(odd[(ri+1)*cx+1:], r)
|
|
}
|
|
|
|
// run
|
|
for {
|
|
print(odd)
|
|
step(even, odd)
|
|
fmt.Scanln()
|
|
|
|
print(even)
|
|
step(odd, even)
|
|
fmt.Scanln()
|
|
}
|
|
}
|
|
|
|
func print(grid []byte) {
|
|
fmt.Println(strings.Repeat("__", cols))
|
|
fmt.Println()
|
|
for r := 1; r <= rows; r++ {
|
|
for c := 1; c <= cols; c++ {
|
|
if grid[r*cx+c] == 0 {
|
|
fmt.Print(" ")
|
|
} else {
|
|
fmt.Printf(" %c", grid[r*cx+c])
|
|
}
|
|
}
|
|
fmt.Println()
|
|
}
|
|
}
|
|
|
|
func step(dst, src []byte) {
|
|
for r := 1; r <= rows; r++ {
|
|
for c := 1; c <= cols; c++ {
|
|
x := r*cx + c
|
|
dst[x] = src[x]
|
|
switch dst[x] {
|
|
case 'H':
|
|
dst[x] = 't'
|
|
case 't':
|
|
dst[x] = '.'
|
|
case '.':
|
|
var nn int
|
|
for _, n := range mn {
|
|
if src[x+n] == 'H' {
|
|
nn++
|
|
}
|
|
}
|
|
if nn == 1 || nn == 2 {
|
|
dst[x] = 'H'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|