adventofcode/helpers/helpers.go

213 lines
3.5 KiB
Go

package aoc
import (
"bufio"
"fmt"
"io/ioutil"
"log"
"os"
"strconv"
"strings"
)
// Some handy Constants
const (
BORDER_NS = "\u2502"
BORDER_WE = "\u2500"
BORDER_NW = "\u250C"
BORDER_NE = "\u2510"
BORDER_SW = "\u2514"
BORDER_SE = "\u2518"
FILL_CHAR = "\u2588"
CLEAR_SCREEN = "\033[H\033[2J"
MAX_INT = int(^uint(0) >> 1)
MIN_INT = -MAX_INT - 1
)
// Find the greatest common denominator
func Gcd(x, y int) int {
for y != 0 {
x, y = y, x%y
}
return x
}
// Find the least common multiple, using 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 AbsInt(i int) int {
if i < 0 {
return i * -1
}
return i
}
func ArgIsSet(a string) bool {
for i := range os.Args {
if os.Args[i] == a || strings.HasPrefix(os.Args[i], a+"=") {
return true
}
}
return false
}
func GetArgValue(a string) string {
for i := range os.Args {
if strings.HasPrefix(os.Args[i], a+"=") {
return strings.TrimPrefix(os.Args[i], a+"=")
}
}
return ""
}
func GetArgNumber(i int) string {
if len(os.Args) > i {
return os.Args[i]
}
return ""
}
func StdinToStringSlice() []string {
var input []string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
input = append(input, scanner.Text())
}
return input
}
func Atoi(i string) int {
var ret int
var err error
if ret, err = strconv.Atoi(i); err != nil {
log.Fatal("Invalid Atoi")
}
return ret
}
func Itoa(i int) string {
return strconv.Itoa(i)
}
func StdinToString() string {
var input string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
input += scanner.Text()
}
return input
}
func FileToStringSlice(fn string) []string {
return strings.Split(string(FileToBytes(fn)), "\n")
}
func FileToString(fn string) string {
return string(FileToBytes(fn))
}
func FileToBytes(fn string) []byte {
var c []byte
var err error
c, err = ioutil.ReadFile(fn)
if err != nil {
fmt.Println("Unable to read file: " + fn)
os.Exit(1)
}
return c
}
func PrintProgress(curr, total int) {
pct := int(float64(curr)/float64(total)) * 100
for i := 0; i < 100; i += 10 {
if pct > i {
fmt.Print(FILL_CHAR)
}
}
}
func StringPermutations(str string) []string {
perms := stringPermHelper(str, 0)
var wrk []string
// Now de-dupe
for i := range perms {
var found bool
for j := range wrk {
if wrk[j] == perms[i] {
found = true
}
}
if !found {
wrk = append(wrk, perms[i])
}
}
return wrk
}
func stringPermHelper(str string, i int) []string {
ret := []string{str}
if i != len(str) {
r := []rune(str)
for j := i; j < len(r); j++ {
r[i], r[j] = r[j], r[i]
ret = append(ret, stringPermHelper(string(r), i+1)...)
r[i], r[j] = r[j], r[i]
}
}
return ret
}
func IntPermutations(inp []int) [][]int {
perms := intPermHelper(inp, 0)
var wrk [][]int
// Now de-dupe
for i := range perms {
var found bool
for j := range wrk {
if IntSlicesAreEqual(perms[i], wrk[j]) {
found = true
break
}
}
if !found {
wrk = append(wrk, perms[i])
}
}
return wrk
}
func intPermHelper(inp []int, i int) [][]int {
ret := [][]int{inp}
if i != len(inp) {
r := make([]int, len(inp))
copy(r, inp)
for j := i; j < len(r); j++ {
r[i], r[j] = r[j], r[i]
ret = append(ret, intPermHelper(r, i+1)...)
r[i], r[j] = r[j], r[i]
}
}
return ret
}
func IntSlicesAreEqual(s1 []int, s2 []int) bool {
if len(s1) != len(s2) {
return false
}
for k := range s1 {
if s1[k] != s2[k] {
return false
}
}
return true
}