func IncrementString(input string) string { runes := slices.StringSlice(strings.Split(input, "")).Reverse() increment := true failed := false for index, rune := range runes { if failed || !increment { continue } switch { case rune == "9": runes[index] = "0" case rune == "Z": runes[index] = "A" case rune >= "0" && rune < "9": fallthrough case rune >= "A" && rune <= "Y": increment = false v := rune[0] v += 1 runes[index] = string(v) default: failed = true } } if increment || failed { return "" } else { return strings.Join(runes.Reverse(), "") } }
func CompactCodes(minimumRangeLength int, codeStrings ...string) (result string, err error) { input := slices.StringSlice(codeStrings) hasCodeRanges := input.Any(func(element string) bool { return strings.Contains(element, "..") }) for index, in := range input { input[index] = strings.TrimSpace(strings.ToUpper(in)) } if hasCodeRanges { err = fmt.Errorf("Input contains code range element ('..')") return } input.Sort() output := make([]string, 0) for index := 0; index < len(input); { rangeEndIndex := index + 1 rangeExpression := "" for ; rangeEndIndex < len(input); rangeEndIndex += 1 { if exp, detected := detectRange(input[index : rangeEndIndex+1]); detected { rangeExpression = exp } else { break } } if rangeExpression != "" && (rangeEndIndex-index) >= minimumRangeLength { output = append(output, rangeExpression) index = rangeEndIndex } else { output = append(output, input[index]) index += 1 } } return strings.Join(output, ","), nil }