Day 4 done
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
package day04
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var ErrNotEnoughSpace = errors.New("not enough space to form word")
|
||||
|
||||
func Handle(input []string) (int, int) {
|
||||
xmas := 0
|
||||
crossMAS := 0
|
||||
for i, line := range input {
|
||||
for j, char := range line {
|
||||
if char == 'X' {
|
||||
xmas += countWord(input, "XMAS", i, j)
|
||||
}
|
||||
if char == 'A' {
|
||||
crossMAS += countCrossPattern(input, "MAS", i, j)
|
||||
}
|
||||
}
|
||||
}
|
||||
return xmas, crossMAS
|
||||
}
|
||||
|
||||
func countWord(matrix []string, word string, posY, posX int) int {
|
||||
wordCount := 0
|
||||
wordLenght := len(word)
|
||||
result, err := getWordHoz(matrix, wordLenght, posY, posX)
|
||||
if err == nil && result == word {
|
||||
wordCount++
|
||||
}
|
||||
result, err = getWordHozRev(matrix, wordLenght, posY, posX)
|
||||
if err == nil && result == word {
|
||||
wordCount++
|
||||
}
|
||||
result, err = getWordVert(matrix, wordLenght, posY, posX)
|
||||
if err == nil && result == word {
|
||||
wordCount++
|
||||
}
|
||||
result, err = getWordVertRev(matrix, wordLenght, posY, posX)
|
||||
if err == nil && result == word {
|
||||
wordCount++
|
||||
}
|
||||
result, err = getWordDiagAsc(matrix, wordLenght, posY, posX)
|
||||
if err == nil && result == word {
|
||||
wordCount++
|
||||
}
|
||||
result, err = getWordDiagAscRev(matrix, wordLenght, posY, posX)
|
||||
if err == nil && result == word {
|
||||
wordCount++
|
||||
}
|
||||
result, err = getWordDiagDesc(matrix, wordLenght, posY, posX)
|
||||
if err == nil && result == word {
|
||||
wordCount++
|
||||
}
|
||||
result, err = getWordDiagDescRev(matrix, wordLenght, posY, posX)
|
||||
if err == nil && result == word {
|
||||
wordCount++
|
||||
}
|
||||
|
||||
return wordCount
|
||||
}
|
||||
|
||||
func countCrossPattern(matrix []string, word string, posY, posX int) int {
|
||||
wordCount := 0
|
||||
wordLenght := len(word)
|
||||
|
||||
result, err := getWordDiagAsc(matrix, wordLenght, posY-1, posX-1)
|
||||
if err == nil && result == word {
|
||||
wordCount++
|
||||
}
|
||||
result, err = getWordDiagAscRev(matrix, wordLenght, posY-1, posX+1)
|
||||
if err == nil && result == word {
|
||||
wordCount++
|
||||
}
|
||||
result, err = getWordDiagDesc(matrix, wordLenght, posY+1, posX-1)
|
||||
if err == nil && result == word {
|
||||
wordCount++
|
||||
}
|
||||
result, err = getWordDiagDescRev(matrix, wordLenght, posY+1, posX+1)
|
||||
if err == nil && result == word {
|
||||
wordCount++
|
||||
}
|
||||
|
||||
if wordCount == 2 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func reverseString(str string) string {
|
||||
runes := []rune(str)
|
||||
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
|
||||
runes[i], runes[j] = runes[j], runes[i]
|
||||
}
|
||||
return string(runes)
|
||||
}
|
||||
|
||||
func getWordHoz(matrix []string, wordLenght, posY, posX int) (string, error) {
|
||||
if posX > len(matrix[posY])-wordLenght {
|
||||
return "", ErrNotEnoughSpace
|
||||
}
|
||||
if posX > len(matrix[posY])-wordLenght-1 {
|
||||
return string(matrix[posY][posX:]), nil
|
||||
}
|
||||
return string(matrix[posY][posX : posX+wordLenght]), nil
|
||||
}
|
||||
|
||||
func getWordHozRev(matrix []string, wordLenght, posY, posX int) (string, error) {
|
||||
if posX < wordLenght-1 {
|
||||
return "", ErrNotEnoughSpace
|
||||
}
|
||||
if posX < wordLenght {
|
||||
word := matrix[posY][0:wordLenght]
|
||||
return reverseString(word), nil
|
||||
}
|
||||
return reverseString(matrix[posY][posX-wordLenght+1 : posX+1]), nil
|
||||
}
|
||||
|
||||
func getWordVert(matrix []string, wordLenght, posY, posX int) (string, error) {
|
||||
if posY > len(matrix)-wordLenght {
|
||||
return "", ErrNotEnoughSpace
|
||||
}
|
||||
word := make([]byte, wordLenght)
|
||||
for i := 0; i < wordLenght; i++ {
|
||||
word[i] = matrix[posY+i][posX]
|
||||
}
|
||||
return string(word), nil
|
||||
}
|
||||
|
||||
func getWordVertRev(matrix []string, wordLenght, posY, posX int) (string, error) {
|
||||
if posY < wordLenght-1 {
|
||||
return "", ErrNotEnoughSpace
|
||||
}
|
||||
word := make([]byte, wordLenght)
|
||||
for i := 0; i < wordLenght; i++ {
|
||||
word[i] = matrix[posY-i][posX]
|
||||
}
|
||||
return string(word), nil
|
||||
}
|
||||
|
||||
func getWordDiagAsc(matrix []string, wordLenght, posY, posX int) (string, error) {
|
||||
if posY > len(matrix)-wordLenght || posX > len(matrix[posY])-wordLenght {
|
||||
return "", ErrNotEnoughSpace
|
||||
}
|
||||
|
||||
word := make([]byte, wordLenght)
|
||||
for i := 0; i < wordLenght; i++ {
|
||||
word[i] = matrix[posY+i][posX+i]
|
||||
}
|
||||
return string(word), nil
|
||||
}
|
||||
|
||||
func getWordDiagAscRev(matrix []string, wordLenght, posY, posX int) (string, error) {
|
||||
if posY > len(matrix)-wordLenght || posX < wordLenght-1 {
|
||||
return "", ErrNotEnoughSpace
|
||||
}
|
||||
|
||||
word := make([]byte, wordLenght)
|
||||
for i := 0; i < wordLenght; i++ {
|
||||
word[i] = matrix[posY+i][posX-i]
|
||||
}
|
||||
return string(word), nil
|
||||
}
|
||||
|
||||
func getWordDiagDesc(matrix []string, wordLenght, posY, posX int) (string, error) {
|
||||
if posY < wordLenght-1 || posX > len(matrix[posY])-wordLenght {
|
||||
return "", ErrNotEnoughSpace
|
||||
}
|
||||
|
||||
word := make([]byte, wordLenght)
|
||||
for i := 0; i < wordLenght; i++ {
|
||||
word[i] = matrix[posY-i][posX+i]
|
||||
}
|
||||
|
||||
return string(word), nil
|
||||
}
|
||||
|
||||
func getWordDiagDescRev(matrix []string, wordLenght, posY, posX int) (string, error) {
|
||||
if posY < wordLenght-1 || posX < wordLenght-1 {
|
||||
return "", ErrNotEnoughSpace
|
||||
}
|
||||
|
||||
word := make([]byte, wordLenght)
|
||||
for i := 0; i < wordLenght; i++ {
|
||||
word[i] = matrix[posY-i][posX-i]
|
||||
}
|
||||
return string(word), nil
|
||||
}
|
||||
Reference in New Issue
Block a user