Files
advent-of-code-2024/day4/xmas.go

116 lines
2.7 KiB
Go
Raw Normal View History

2024-12-04 17:47:16 +01:00
package main
import (
"fmt"
"os"
"regexp"
"strings"
)
func check(e error) {
if e != nil { panic(e) }
}
func rune_matrix(text string) [][]rune {
lines := strings.Split(text, "\n")
matrix := make([][]rune, len(lines))
for i := range matrix {
matrix[i] = make([]rune, 0, len(lines[0]))
}
for i, line := range lines {
for _, c := range []rune(line) {
matrix[i] = append(matrix[i], c)
}
}
return matrix
}
func rune_matrix_to_string(matrix [][]rune) string {
lines := make([]string, 0, len(matrix))
for _, line := range matrix {
lines = append(lines, string(line))
}
return strings.Join(lines, "\n")
}
func transpose(text string) string {
matrix := rune_matrix(text)
matrix_T := make([][]rune, len(matrix[0]))
for i := range matrix[0] {
matrix_T[i] = make([]rune, len(matrix))
}
for i := range matrix {
for j := range matrix[0] {
matrix_T[j][i] = matrix[i][j]
}
}
return rune_matrix_to_string(matrix_T)
}
func abs(n int) int {
if n < 0 { return -n }
return n
}
func shear(text string, offset int) string {
lines := strings.Split(text, "\n")
max_len := 0
// add left padding
for pad_left := range lines {
lines[pad_left] = strings.Repeat(" ", abs(pad_left - offset)) + lines[pad_left]
max_len = max(max_len, len(lines[pad_left]))
}
// make square again by adding right padding
var pad_right int
for i := range lines {
pad_right = max_len - len(lines[i])
lines[i] = lines[i] + strings.Repeat(" ", pad_right)
}
return strings.Join(lines, "\n")
}
func main() {
dat, err := os.ReadFile("data.txt")
check(err)
dat_str := string(dat[:len(dat) - 1])
matches := 0
// split so that overlapping ones are also matched
r1 := regexp.MustCompile("XMAS")
r2 := regexp.MustCompile("SAMX")
// horizontal
matches += len(r1.FindAllStringIndex(dat_str, -1))
matches += len(r2.FindAllStringIndex(dat_str, -1))
// vertical
matches += len(r1.FindAllStringIndex(transpose(dat_str), -1))
matches += len(r2.FindAllStringIndex(transpose(dat_str), -1))
// increasing left padding + transpose (shear)
matches += len(r1.FindAllStringIndex(transpose(shear(dat_str, 0)), -1))
matches += len(r2.FindAllStringIndex(transpose(shear(dat_str, 0)), -1))
// decreasing left padding + transpose (shear)
r := regexp.MustCompile("\n")
offset := r.FindStringIndex(dat_str)[0] - 1
matches += len(r1.FindAllStringIndex(transpose(shear(dat_str, offset)), -1))
matches += len(r2.FindAllStringIndex(transpose(shear(dat_str, offset)), -1))
fmt.Println(matches)
}