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]) // split so that overlapping ones are also matched r1 := regexp.MustCompile("MAS") r2 := regexp.MustCompile("SAM") r_nl := regexp.MustCompile("\n") offset := r_nl.FindStringIndex(dat_str)[0] - 1 r_dot := regexp.MustCompile("\\.") // increasing left padding + transpose (shear) a_replaced_i1 := r1.ReplaceAllString(transpose(shear(dat_str, 0)), "M.S") a_replaced_i2 := r2.ReplaceAllString(transpose(shear(dat_str, 0)), "S.M") a_replaced_i1 = shear(transpose(a_replaced_i1), offset) a_replaced_i2 = shear(transpose(a_replaced_i2), offset) //fmt.Println(a_replaced_i1, "\n") //fmt.Println(r_dot.FindAllStringIndex(a_replaced_i1, -1), "\n") //fmt.Println(a_replaced_i2, "\n") //fmt.Println(r_dot.FindAllStringIndex(a_replaced_i2, -1), "\n") dot_indices_i := r_dot.FindAllStringIndex(a_replaced_i1, -1) dot_indices_i = append(dot_indices_i, r_dot.FindAllStringIndex(a_replaced_i2, -1)...) //fmt.Println(dot_indices_i) // decreasing left padding + transpose (shear) a_replaced_d1 := r1.ReplaceAllString(transpose(shear(dat_str, offset)), "M.S") a_replaced_d2 := r2.ReplaceAllString(transpose(shear(dat_str, offset)), "S.M") a_replaced_d1 = shear(transpose(a_replaced_d1), 0) a_replaced_d2 = shear(transpose(a_replaced_d2), 0) //fmt.Println(a_replaced_d1, "\n") //fmt.Println(a_replaced_d2, "\n") dot_indices_d := r_dot.FindAllStringIndex(a_replaced_d1, -1) dot_indices_d = append(dot_indices_d, r_dot.FindAllStringIndex(a_replaced_d2, -1)...) //fmt.Println(dot_indices_d) // count duplicates matches := 0 for _, elem1 := range dot_indices_i { for _, elem2 := range dot_indices_d { if elem1[0] == elem2[0] { matches++ break } } } fmt.Println(matches) }