191 lines
4.7 KiB
Go
191 lines
4.7 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
func main() {
|
|
if len(os.Args) < 2 {
|
|
panic("Provide input file")
|
|
}
|
|
inputFile := os.Args[1]
|
|
|
|
part1 := part1(inputFile)
|
|
fmt.Printf("(%s) Part 1: %d\n", inputFile, part1)
|
|
|
|
part2 := part2(inputFile)
|
|
fmt.Printf("(%s) Part 2: %d\n", inputFile, part2)
|
|
}
|
|
|
|
func part2(inputFile string) int {
|
|
input, err := os.Open(inputFile)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer input.Close()
|
|
|
|
wordSearch := make([][]rune, 0)
|
|
row := 0
|
|
for {
|
|
var line string
|
|
_, err := fmt.Fscanf(input, "%s\n", &line)
|
|
if err != nil {
|
|
break
|
|
}
|
|
|
|
wordSearch = append(wordSearch, make([]rune, len(line)))
|
|
for i, c := range line {
|
|
wordSearch[row][i] = c
|
|
}
|
|
row++
|
|
}
|
|
|
|
return crossSearchMap(wordSearch)
|
|
}
|
|
|
|
func crossSearchMap(wordSearch [][]rune) int {
|
|
possibilities := make([][]int, len(wordSearch))
|
|
for i := range possibilities {
|
|
possibilities[i] = make([]int, len(wordSearch[i]))
|
|
}
|
|
|
|
count := 0
|
|
for y, row := range wordSearch {
|
|
for x, c := range row {
|
|
if c == 'A' {
|
|
if crossCheck(wordSearch, x, y) {
|
|
count++
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
func crossCheck(wordSearch [][]rune, x, y int) bool {
|
|
downLeft := false
|
|
downRight := false
|
|
if y-1 >= 0 && y+1 < len(wordSearch) && x-1 >= 0 && x+1 < len(wordSearch[y]) {
|
|
fmt.Printf("Checking cross at %d,%d\n", x, y)
|
|
fmt.Printf("Checking %c %c\n", wordSearch[y-1][x-1], wordSearch[y+1][x+1])
|
|
if wordSearch[y-1][x-1] == 'M' && wordSearch[y+1][x+1] == 'S' {
|
|
downLeft = true
|
|
} else if wordSearch[y-1][x-1] == 'S' && wordSearch[y+1][x+1] == 'M' {
|
|
downLeft = true
|
|
}
|
|
fmt.Printf("Checking %c %c\n", wordSearch[y+1][x-1], wordSearch[y-1][x+1])
|
|
if wordSearch[y-1][x+1] == 'M' && wordSearch[y+1][x-1] == 'S' {
|
|
downRight = true
|
|
} else if wordSearch[y-1][x+1] == 'S' && wordSearch[y+1][x-1] == 'M' {
|
|
downRight = true
|
|
}
|
|
}
|
|
if downLeft && downRight {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func part1(inputFile string) int {
|
|
input, err := os.Open(inputFile)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer input.Close()
|
|
|
|
wordSearch := make([][]rune, 0)
|
|
row := 0
|
|
for {
|
|
var line string
|
|
_, err := fmt.Fscanf(input, "%s\n", &line)
|
|
if err != nil {
|
|
break
|
|
}
|
|
|
|
wordSearch = append(wordSearch, make([]rune, len(line)))
|
|
for i, c := range line {
|
|
wordSearch[row][i] = c
|
|
}
|
|
row++
|
|
}
|
|
|
|
return searchMap(wordSearch)
|
|
}
|
|
|
|
// finds X's and then calls xmas to see if it makes 'XMAS'
|
|
func searchMap(wordSearch [][]rune) int {
|
|
count := 0
|
|
for y, row := range wordSearch {
|
|
for x, c := range row {
|
|
if c == 'X' {
|
|
count += xmas(wordSearch, x, y)
|
|
}
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
func xmas(wordSearch [][]rune, x, y int) int {
|
|
count := 0
|
|
|
|
// fmt.Printf("Checking XMAS at %d,%d\n", x, y)
|
|
// check up
|
|
if y-3 >= 0 {
|
|
// fmt.Printf("Checking %c %c %c\n", wordSearch[y-1][x], wordSearch[y-2][x], wordSearch[y-3][x])
|
|
if wordSearch[y-1][x] == 'M' && wordSearch[y-2][x] == 'A' && wordSearch[y-3][x] == 'S' {
|
|
count++
|
|
}
|
|
}
|
|
// check up-left
|
|
if y-3 >= 0 && x-3 >= 0 {
|
|
// fmt.Printf("Checking %c %c %c\n", wordSearch[y-1][x-1], wordSearch[y-2][x-2], wordSearch[y-3][x-3])
|
|
if wordSearch[y-1][x-1] == 'M' && wordSearch[y-2][x-2] == 'A' && wordSearch[y-3][x-3] == 'S' {
|
|
count++
|
|
}
|
|
}
|
|
// check left
|
|
if x-3 >= 0 {
|
|
// fmt.Printf("Checking %c %c %c\n", wordSearch[y][x-1], wordSearch[y][x-2], wordSearch[y][x-3])
|
|
if wordSearch[y][x-1] == 'M' && wordSearch[y][x-2] == 'A' && wordSearch[y][x-3] == 'S' {
|
|
count++
|
|
}
|
|
}
|
|
// check down-left
|
|
if y+3 < len(wordSearch) && x-3 >= 0 {
|
|
// fmt.Printf("Checking %c %c %c\n", wordSearch[y+1][x-1], wordSearch[y+2][x-2], wordSearch[y+3][x-3])
|
|
if wordSearch[y+1][x-1] == 'M' && wordSearch[y+2][x-2] == 'A' && wordSearch[y+3][x-3] == 'S' {
|
|
count++
|
|
}
|
|
}
|
|
// check down
|
|
if y+3 < len(wordSearch) {
|
|
// fmt.Printf("Checking %c %c %c\n", wordSearch[y+1][x], wordSearch[y+2][x], wordSearch[y+3][x])
|
|
if wordSearch[y+1][x] == 'M' && wordSearch[y+2][x] == 'A' && wordSearch[y+3][x] == 'S' {
|
|
count++
|
|
}
|
|
}
|
|
// check down-right
|
|
if y+3 < len(wordSearch) && x+3 < len(wordSearch[y]) {
|
|
// fmt.Printf("Checking %c %c %c\n", wordSearch[y+1][x+1], wordSearch[y+2][x+2], wordSearch[y+3][x+3])
|
|
if wordSearch[y+1][x+1] == 'M' && wordSearch[y+2][x+2] == 'A' && wordSearch[y+3][x+3] == 'S' {
|
|
count++
|
|
}
|
|
}
|
|
// check right
|
|
if x+3 < len(wordSearch[y]) {
|
|
// fmt.Printf("Checking %c %c %c\n", wordSearch[y][x+1], wordSearch[y][x+2], wordSearch[y][x+3])
|
|
if wordSearch[y][x+1] == 'M' && wordSearch[y][x+2] == 'A' && wordSearch[y][x+3] == 'S' {
|
|
count++
|
|
}
|
|
}
|
|
// check up-right
|
|
if y-3 >= 0 && x+3 < len(wordSearch[y]) {
|
|
// fmt.Printf("Checking %c %c %c\n", wordSearch[y-1][x+1], wordSearch[y-2][x+2], wordSearch[y-3][x+3])
|
|
if wordSearch[y-1][x+1] == 'M' && wordSearch[y-2][x+2] == 'A' && wordSearch[y-3][x+3] == 'S' {
|
|
count++
|
|
}
|
|
}
|
|
return count
|
|
}
|