86 lines
1.8 KiB
Go
86 lines
1.8 KiB
Go
|
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"
|
||
|
}
|