package main import ( "fmt" h "git.bullercodeworks.com/brian/adventofcode/helpers" ) func main() { inp := h.StdinToCoordMap() part1(inp) part2(inp) } func part1(m h.CoordByteMap) { var total int for y := m.TLY; y <= m.BRY; y++ { for x := m.TLX; x <= m.BRX; x++ { total += checkPos(m, h.Coordinate{X: x, Y: y}) } } fmt.Println("# Part 1") fmt.Println("Instances of XMAS:", total) } func part2(m h.CoordByteMap) { var total int for y := m.TLY; y <= m.BRY; y++ { for x := m.TLX; x <= m.BRX; x++ { if checkXPos(m, h.Coordinate{X: x, Y: y}) { total++ } } } fmt.Println("# Part 2") fmt.Println("Instances of X-MAS:", total) } // checkPos takes an x,y and returns how many instances of // 'XMAS' occur starting there. func checkPos(m h.CoordByteMap, c h.Coordinate) int { if m.Get(c) != 'X' { return 0 } var total int for _, dir := range []h.Coordinate{ {X: -1, Y: 0}, // North {X: -1, Y: 1}, // Northeast {X: 0, Y: 1}, // East {X: 1, Y: 1}, // Southeast {X: 1, Y: 0}, // South {X: 1, Y: -1}, // Southwest {X: 0, Y: -1}, // West {X: -1, Y: -1}, // Northwest } { if checkDir(m, c, dir, []byte{'X', 'M', 'A', 'S'}) { total++ } } return total } // checkDir follows a direction to look for the word returning true if found. func checkDir(m h.CoordByteMap, c h.Coordinate, dir h.Coordinate, word []byte) bool { if len(word) == 0 { return true } if m.Get(c) != word[0] { return false } return checkDir(m, c.Relative(dir), dir, word[1:]) } func checkXPos(m h.CoordByteMap, c h.Coordinate) bool { if m.Get(c) != 'A' { return false } // A X-Mas can be: // M S S M M M S S // A A A A // M S S M S S M M wrk := string([]byte{m.Get(c.NE()), m.Get(c.SW()), m.Get(c.NW()), m.Get(c.SE())}) return wrk == "MSMS" || wrk == "SMSM" || wrk == "MSSM" || wrk == "SMMS" }