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.
194 lines
3.0 KiB
Go
194 lines
3.0 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(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
|
|
}
|
|
|
|
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
|
|
}
|