You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

213 lines
3.4 KiB
Go

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(strings.TrimSpace(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(strings.TrimSpace(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
}
func Reduce[T, M any](s []T, initValue M, f func(M, T) M) M {
acc := initValue
for _, v := range s {
acc = f(acc, v)
}
return acc
}
func Map[T, M any](s []T, f func(T) M) []M {
res := []M{}
for _, v := range s {
res = append(res, f(v))
}
return res
}
func DuplicateMatrix[T any](matrix [][]T) [][]T {
duplicate := make([][]T, len(matrix))
for i := range matrix {
duplicate[i] = make([]T, len(matrix[i]))
copy(duplicate[i], matrix[i])
}
return duplicate
}
func CloneMap[K comparable, V any](src map[K]V) map[K]V {
dst := map[K]V{}
for k, v := range src {
dst[k] = v
}
return dst
}