diff --git a/unpack.go b/unpack.go index ddffac4..ea9a1bd 100644 --- a/unpack.go +++ b/unpack.go @@ -2,28 +2,78 @@ package unpackstring import ( "errors" - "regexp" + "strconv" + "strings" + "unicode" ) var ErrInvalidString = errors.New("invalid string") +type state int + +const ( + start state = iota + escape + number +) + func Unpack(str string) (string, error) { - // Place your code here. - err := CheckString(str) - if err != nil { - return "", err + var currentState state = start + var result strings.Builder + numOfRepeat := 1 + //if firstCheckString(&str) == true { + // return "", ErrInvalidString + //} + + var runeArray = []rune(str) + + if len(runeArray) > 0 && unicode.IsDigit(runeArray[0]) { + return "first rune is digit", ErrInvalidString } + for i, char := range runeArray { + + switch currentState { + case start: + if unicode.IsDigit(char) { + currentState = number + numOfRepeat, _ = strconv.Atoi(string(char)) + } else if char == '\\' { + currentState = escape + } else { + currentState = start + result.WriteRune(char) + } + case number: + if unicode.IsDigit(char) { + return "", ErrInvalidString + } + repStr, err := repeatRune(runeArray[i-2], numOfRepeat) + if err != nil { + res := result.String() + result.Reset() + result.WriteString(res[0 : len(res)-1]) + } + result.WriteString(repStr) + currentState = start + result.WriteRune(char) + case escape: + result.WriteRune(char) + + } + + } + + return result.String(), nil + +} + +func repeatRune(char rune, numOfRepeat int) (string, error) { + if numOfRepeat > 0 { + return strings.Repeat(string(char), numOfRepeat-1), nil + } + if numOfRepeat == 0 { + return "", errors.New("zero repeat") + } return "", nil } - -func CheckString(str string) error { - - re, _ := regexp.Compile(`^\d|\d{2,}`) - - if re.MatchString(str) == true { - return ErrInvalidString - } - - return nil -}