adventofcode/2024/day04/main.go

86 lines
1.8 KiB
Go
Raw Normal View History

2024-12-04 14:14:00 +00:00
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"
}