package main import ( "bufio" "fmt" "os" "strings" ) func main() { fmt.Println(part1(readData("example.txt"))) fmt.Println(part1(readData("data.txt"))) fmt.Println(part2(readData("example2.txt"))) fmt.Println(part2(readData("data.txt"))) } func readData(fileName string) (output []string) { fp, err := os.Open(fileName) if err != nil { panic(err) } scanner := bufio.NewScanner(fp) output = make([]string, 0) for scanner.Scan() { output = append(output, strings.TrimSpace(scanner.Text())) } return } func part1(s []string) (count int) { width := len(s[0]) height := len(s) for y := 0; y < height; y++ { for x := 0; x < width; x++ { if s[y][x] == 'X' { count += checkXmas0(s, x, y) } } } return } func checkXmas0(s []string, x, y int) (count int) { count += checkXmas1(s, x, y, 0) if x >= 3 { count += checkXmas1(s, x, y, -1) } if x < len(s[0])-3 { count += checkXmas1(s, x, y, 1) } return } func checkXmas1(s []string, x, y, dx int) (count int) { count += checkXmas2(s, x, y, dx, 0) if y >= 3 { count += checkXmas2(s, x, y, dx, -1) } if y < len(s)-3 { count += checkXmas2(s, x, y, dx, 1) } return } const WORD string = "XMAS" func checkXmas2(s []string, x, y, dx, dy int) int { if dx == 0 && dy == 0 { return 0 } for i := 0; i < 4; i++ { if s[y][x] != WORD[i] { return 0 } x += dx y += dy } return 1 } func part2(s []string) (count int) { width := len(s[0]) height := len(s) str := []byte{0, 0, 0, 0} for y := 1; y < height-1; y++ { for x := 1; x < width-1; x++ { if s[y][x] == 'A' { str[0] = s[y-1][x-1] str[1] = s[y-1][x+1] str[2] = s[y+1][x+1] str[3] = s[y+1][x-1] count += checkXMas(str) } } } return } func checkXMas(b []byte) int { i := 3 j := 0 for n := 0; n < 4; n++ { if b[i] == 'S' && b[j] == 'M' { break } i = j j += 1 } if b[j%4] == 'M' && b[(j+1)%4] == 'M' && b[(j+2)%4] == 'S' && b[(j+3)%4] == 'S' { return 1 } return 0 }