92 lines
1.7 KiB
Go
92 lines
1.7 KiB
Go
package day04
|
|
|
|
import (
|
|
"strings"
|
|
)
|
|
|
|
var directions = [8][2]int{
|
|
{0, 1},
|
|
{0, -1},
|
|
{1, 0},
|
|
{-1, 0},
|
|
{1, 1},
|
|
{1, -1},
|
|
{-1, 1},
|
|
{-1, -1},
|
|
}
|
|
|
|
func Part1(input string) int {
|
|
grid := parseInput(input)
|
|
return countXMAS(grid)
|
|
}
|
|
|
|
func Part2(input string) int {
|
|
grid := parseInput(input)
|
|
return countXMASPatterns(grid)
|
|
}
|
|
|
|
func parseInput(input string) [][]rune {
|
|
lines := strings.Split(strings.TrimSpace(input), "\n")
|
|
grid := make([][]rune, len(lines))
|
|
for i, line := range lines {
|
|
grid[i] = []rune(line)
|
|
}
|
|
return grid
|
|
}
|
|
|
|
func countXMAS(grid [][]rune) int {
|
|
rows := len(grid)
|
|
cols := len(grid[0])
|
|
target := "XMAS"
|
|
total := 0
|
|
|
|
for r := 0; r < rows; r++ {
|
|
for c := 0; c < cols; c++ {
|
|
for _, d := range directions {
|
|
dr, dc := d[0], d[1]
|
|
found := true
|
|
|
|
for k := 0; k < len(target); k++ {
|
|
nr := r + k*dr
|
|
nc := c + k*dc
|
|
if nr < 0 || nr >= rows || nc < 0 || nc >= cols || grid[nr][nc] != rune(target[k]) {
|
|
found = false
|
|
break
|
|
}
|
|
}
|
|
|
|
if found {
|
|
total++
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return total
|
|
}
|
|
|
|
func countXMASPatterns(grid [][]rune) int {
|
|
rows := len(grid)
|
|
cols := len(grid[0])
|
|
total := 0
|
|
|
|
for r := 1; r < rows-1; r++ {
|
|
for c := 1; c < cols-1; c++ {
|
|
|
|
topLeft := grid[r-1][c-1]
|
|
topRight := grid[r-1][c+1]
|
|
center := grid[r][c]
|
|
bottomLeft := grid[r+1][c-1]
|
|
bottomRight := grid[r+1][c+1]
|
|
|
|
if center == 'A' && ((topLeft == 'S' && topRight == 'S' && bottomLeft == 'M' && bottomRight == 'M') ||
|
|
(topLeft == 'S' && topRight == 'M' && bottomLeft == 'S' && bottomRight == 'M') ||
|
|
(topLeft == 'M' && topRight == 'M' && bottomLeft == 'S' && bottomRight == 'S') ||
|
|
(topLeft == 'M' && topRight == 'S' && bottomLeft == 'M' && bottomRight == 'S')) {
|
|
total++
|
|
}
|
|
}
|
|
}
|
|
|
|
return total
|
|
}
|