package door import ( "bytes" "strconv" "strings" "golang.org/x/text/width" ) // https://siongui.github.io/2016/03/23/go-utf8-string-width/ // Return width of Unicode rune. func UnicodeWidth(r rune) int { p := width.LookupRune(r) if p.Kind() == width.EastAsianWide { return 2 } return 1 } // Delete an item from an array, returning item and true on success. func ArrayDelete[T any](stack *[]T, pos int) (T, bool) { // log.Printf("Array %d, %d\n", len(*stack), cap(*stack)) var result T /* https://stackoverflow.com/questions/33834742/remove-and-adding-elements-to-array-in-go-lang https://github.com/golang/go/wiki/SliceTricks */ if pos < 0 || pos > len(*stack) { return result, false } result = (*stack)[pos] copy((*stack)[pos:], (*stack)[pos+1:]) // var temp T // (*stack)[len(*stack)-1] = temp *stack = (*stack)[:len(*stack)-1] return result, true } // Pop items from head of array, return true on success. func ArrayPop[T any](stack *[]T, count int) bool { /* https://stackoverflow.com/questions/33834742/remove-and-adding-elements-to-array-in-go-lang https://github.com/golang/go/wiki/SliceTricks */ if count < 0 || count > len(*stack) { return false } copy((*stack)[0:], (*stack)[count:]) // var temp T // (*stack)[len(*stack)-1] = temp *stack = (*stack)[:len(*stack)-count] return true } // Split string on separator, returning []int func SplitToInt(input string, sep string) []int { var result []int for _, number := range strings.Split(input, sep) { v, err := strconv.Atoi(number) if err == nil { result = append(result, v) } } return result } // In unicode, a single character isn't always 1 char wide. // This finds the actual length. // Calculate the length of the given line, dealing with unicode. func StringLen(s []byte) int { if Unicode { var len int var ubuff *bytes.Buffer = bytes.NewBuffer(s) for { r, _, err := ubuff.ReadRune() if err != nil { break } len += UnicodeWidth(r) } return len } else { return len(s) } }