package utils import ( "bufio" "log" "os" "strconv" "strings" ) func ReadLines(fileName string) []string { result := []string{} file, err := os.Open(fileName) if err != nil { log.Fatal(err) } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { result = append(result, scanner.Text()) } if err := scanner.Err(); err != nil { log.Fatal(err) } return result } func ParseIntArray(s string, sep string) []int { result := []int{} var vals []string if sep == " " { vals = strings.Fields(strings.TrimSpace(s)) } else { vals = strings.Split(strings.TrimSpace(s), sep) } for _, val := range vals { n, _ := strconv.Atoi(val) result = append(result, n) } return result } func ParseInt64Array(s string, sep string) []int64 { result := []int64{} var vals []string if sep == " " { vals = strings.Fields(strings.TrimSpace(s)) } else { vals = strings.Split(strings.TrimSpace(s), sep) } for _, val := range vals { n, _ := strconv.ParseInt(val, 10, 64) result = append(result, n) } return result } func IntPow(x int, y int) int { result := 1 for i := 0; i < y; i++ { result *= x } return result } func Int64Pow(x int64, y int64) int64 { result := int64(1) for i := int64(0); i < y; i++ { result *= x } return result } func Pow2(x int) int { return 1 << x } // greatest common divisor (GCD) via Euclidean algorithm func GCD(a, b int) int { for b != 0 { t := b b = a % b a = t } return a } // find Least Common Multiple (LCM) via GCD func LCM(a, b int, integers ...int) int { result := a * b / GCD(a, b) for i := 0; i < len(integers); i++ { result = LCM(result, integers[i]) } return result } func Fold[A any, T any](a A, s []T, f func(A, T) A) A { for i := range s { a = f(a, s[i]) } return a } func AbsInt(x int) int { if x >= 0 { return x } else { return -x } } func SplitNoBlank(s string, sep string) []string { splitted_line := strings.Split(s, sep) result := []string{} for _, part := range splitted_line { if part != "" { result = append(result, part) } } return result } func Transpose[T any](slice [][]T) [][]T { xl := len(slice[0]) yl := len(slice) result := make([][]T, xl) for i := range result { result[i] = make([]T, yl) } for i := 0; i < xl; i++ { for j := 0; j < yl; j++ { result[i][j] = slice[j][i] } } return result } func RotateClockwise[T any](slice [][]T) [][]T { xl := len(slice[0]) yl := len(slice) result := make([][]T, xl) for i := range result { result[i] = make([]T, yl) } /* r=0,c=0 -> c,width-1-r r=0,c=1 -> c,width-1 r=1, c=0 -> c, width-1-r */ for row := 0; row < yl; row++ { for col := 0; col < xl; col++ { result[col][yl-1-row] = slice[row][col] } } return result }