123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- package main
- import (
- "bufio"
- "errors"
- "fmt"
- "io"
- "log"
- "os"
- )
- const MAX_LOOP = 1_000_000
- func trim(bs []byte) []byte {
- last := len(bs) - 1
- if last >= 0 && bs[last] == '\n' {
- return bs[:last]
- }
- return bs
- }
- func main() {
- var dim int
- var rows [][]byte
- r := bufio.NewReader(os.Stdin)
- line, err := r.ReadBytes('\n')
- if err != nil {
- log.Fatalf("While reading input: %v", err)
- }
- line = trim(line)
- dim = len(line)
- rows = make([][]byte, dim)
- rows[0] = line
- for i := 1; i < dim; i++ {
- line, err = r.ReadBytes('\n')
- if errors.Is(err, io.EOF) {
- break
- }
- if err != nil {
- log.Fatalf("While reading input: %v", err)
- }
- rows[i] = trim(line)
- }
- diags := dim - 4 + dim - 4 + 1
- ctrs := 1 + dim + diags + diags
- bufs := make([]byte, ctrs*4)
- offset := 0
- horizontal := make([]*Counter, 1)
- horizontal[0] = new(Counter)
- horizontal[0].Init(bufs[offset : offset+4])
- offset += 4
- vertical := make([]*Counter, dim)
- for i := 0; i < dim; i++ {
- vertical[i] = new(Counter)
- vertical[i].Init(bufs[offset : offset+4])
- offset += 4
- }
- swDiag := make([]*Counter, diags)
- for i := 0; i < diags; i++ {
- swDiag[i] = new(Counter)
- swDiag[i].Init(bufs[offset : offset+4])
- offset += 4
- }
- seDiag := make([]*Counter, diags)
- for i := 0; i < diags; i++ {
- seDiag[i] = new(Counter)
- seDiag[i].Init(bufs[offset : offset+4])
- offset += 4
- }
- diagLag := 3
- for i := 0; i < dim; i++ {
- horizontal[0].Reset()
- for j := 0; j < dim; j++ {
- e := rows[i][j]
- horizontal[0].Event(e)
- vertical[j].Event(e)
- swIdx := i + j - diagLag
- if 0 <= swIdx && swIdx < diags {
- swDiag[swIdx].Event(e)
- }
- seIdx := j - i - (diagLag + 1 - dim)
- if 0 <= seIdx && seIdx < diags {
- seDiag[seIdx].Event(e)
- }
- }
- }
- sum := 0
- for _, c := range horizontal {
- sum += c.Count()
- }
- for _, c := range vertical {
- sum += c.Count()
- }
- for _, c := range swDiag {
- sum += c.Count()
- }
- for _, c := range seDiag {
- sum += c.Count()
- }
- fmt.Println(sum)
- }
- type Counter struct {
- cnt int
- buf []byte
- }
- func (c *Counter) Init(buf []byte) {
- c.buf = buf
- }
- func (c *Counter) Reset() {
- c.buf = c.buf[:0]
- }
- func (c *Counter) Event(e byte) {
- switch {
- case e == 'X' && string(c.buf) == "SAM" ||
- e == 'S' && string(c.buf) == "XMA":
- c.cnt++
- c.Reset()
- c.buf = append(c.buf, e)
- case e == 'M' && string(c.buf) == "SA" ||
- e == 'A' && string(c.buf) == "S" ||
- e == 'S' && string(c.buf) == "" ||
- e == 'A' && string(c.buf) == "XM" ||
- e == 'M' && string(c.buf) == "X" ||
- e == 'X' && string(c.buf) == "":
- c.buf = append(c.buf, e)
- default:
- c.Reset()
- c.buf = append(c.buf, e)
- }
- }
- func (c *Counter) Count() int {
- return c.cnt
- }
|