180 lines
3.6 KiB
Go
180 lines
3.6 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
)
|
|
|
|
type direction struct {
|
|
X int
|
|
Y int
|
|
}
|
|
|
|
var (
|
|
undef direction = direction{0, 0}
|
|
north direction = direction{-1, 0}
|
|
north_east direction = direction{-1, 1}
|
|
east direction = direction{0, 1}
|
|
south_east direction = direction{1, 1}
|
|
south direction = direction{1, 0}
|
|
south_west direction = direction{1, -1}
|
|
west direction = direction{0, -1}
|
|
north_west direction = direction{-1, -1}
|
|
)
|
|
|
|
func checkX_MAS(field [][]string, x int, y int) bool {
|
|
ne := getChar(field, x+north_east.X, y+north_east.Y)
|
|
se := getChar(field, x+south_east.X, y+south_east.Y)
|
|
sw := getChar(field, x+south_west.X, y+south_west.Y)
|
|
nw := getChar(field, x+north_west.X, y+north_west.Y)
|
|
|
|
// All allowed options
|
|
// M.S
|
|
// .A.
|
|
// M.S
|
|
//
|
|
// S.S
|
|
// .A.
|
|
// M.M
|
|
//
|
|
// S.M
|
|
// .A.
|
|
// S.M
|
|
//
|
|
// M.M
|
|
// .A.
|
|
// S.S
|
|
|
|
pattern := fmt.Sprintf("%s%s%s%s", ne, se, sw, nw)
|
|
if pattern == "SSMM" || pattern == "SMMS" || pattern == "MMSS" || pattern == "MSSM" {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func getChar(field [][]string, x, y int) string {
|
|
bound_x := len(field)
|
|
if x == -1 || x >= bound_x {
|
|
return ""
|
|
}
|
|
bound_y := len(field[x])
|
|
if y == -1 || y >= bound_y {
|
|
return ""
|
|
}
|
|
|
|
return field[x][y]
|
|
}
|
|
|
|
func main() {
|
|
content, err := os.ReadFile("./input.txt")
|
|
if err != nil {
|
|
log.Fatalf("failed to open file: %s\n", err)
|
|
}
|
|
|
|
var field [][]string
|
|
|
|
x_axis := 0
|
|
y_axis := 0
|
|
|
|
result2 := 0
|
|
|
|
for _, b := range content {
|
|
char := string(b)
|
|
if char == "\n" {
|
|
x_axis++
|
|
y_axis = 0
|
|
continue
|
|
}
|
|
|
|
if y_axis == 0 {
|
|
field = append(field, make([]string, 0))
|
|
}
|
|
|
|
field[x_axis] = append(field[x_axis], char)
|
|
|
|
y_axis++
|
|
}
|
|
|
|
var found [][]pos
|
|
|
|
for x := 0; x < len(field); x++ {
|
|
for y := 0; y < len(field[x]); y++ {
|
|
if field[x][y] == "X" {
|
|
seq := []pos{}
|
|
seq = append(seq, pos{x, y})
|
|
checkXMAS(field, x+north.X, y+north.Y, seq, &found, north)
|
|
checkXMAS(field, x+north_east.X, y+north_east.Y, seq, &found, north_east)
|
|
checkXMAS(field, x+east.X, y+east.Y, seq, &found, east)
|
|
checkXMAS(field, x+south_east.X, y+south_east.Y, seq, &found, south_east)
|
|
checkXMAS(field, x+south.X, y+south.Y, seq, &found, south)
|
|
checkXMAS(field, x+south_west.X, y+south_west.Y, seq, &found, south_west)
|
|
checkXMAS(field, x+west.X, y+west.Y, seq, &found, west)
|
|
checkXMAS(field, x+north_west.X, y+north_west.Y, seq, &found, north_west)
|
|
|
|
}
|
|
if field[x][y] == "A" {
|
|
if checkX_MAS(field, x, y) {
|
|
result2++
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fmt.Println("result part 1: ", len(found))
|
|
fmt.Println("result part 2: ", result2)
|
|
}
|
|
|
|
type pos struct {
|
|
X int
|
|
Y int
|
|
}
|
|
|
|
func seqToString(field [][]string, seq []pos) string {
|
|
str := ""
|
|
for _, p := range seq {
|
|
str += field[p.X][p.Y]
|
|
}
|
|
return str
|
|
}
|
|
|
|
func checkXMAS(field [][]string, x int, y int, current_seq []pos, found *[][]pos, dir direction) {
|
|
char := getChar(field, x, y)
|
|
if char == "" {
|
|
return
|
|
}
|
|
|
|
seq_str := seqToString(field, current_seq)
|
|
|
|
if (seq_str == "" && char == "X") ||
|
|
(seq_str == "X" && char == "M") ||
|
|
(seq_str == "XM" && char == "A") ||
|
|
(seq_str == "XMA" && char == "S") {
|
|
|
|
pos := pos{X: x, Y: y}
|
|
current_seq = append(current_seq, pos)
|
|
} else {
|
|
return
|
|
}
|
|
|
|
if seqToString(field, current_seq) == "XMAS" {
|
|
*found = append(*found, current_seq)
|
|
}
|
|
|
|
// nort = -1, 0
|
|
// north_east = -1, 1
|
|
// east = 0, 1
|
|
// south_east = 1, 1
|
|
// south = 1, 0
|
|
// south_west = 1, -1
|
|
// west = 0, -1
|
|
|
|
// [0, 0] [0, 1] [0, 2] [0, 3]
|
|
// [1, 0] [1, 1] [1, 2] [1, 3]
|
|
// [2, 0] [2, 1] [2, 2] [2, 3]
|
|
// [3, 0] [3, 1] [3, 2] [3, 3]
|
|
|
|
checkXMAS(field, x+dir.X, y+dir.Y, current_seq, found, dir)
|
|
}
|