Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion hw02_unpack_string/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ go 1.16
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/stretchr/testify v1.7.0
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
90 changes: 87 additions & 3 deletions hw02_unpack_string/unpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,95 @@ package hw02unpackstring

import (
"errors"
"strconv"
"strings"
"unicode"
)

var ErrInvalidString = errors.New("invalid string")

func Unpack(_ string) (string, error) {
// Place your code here.
return "", nil
func Unpack(v string) (string, error) {
if v == "" {
return "", nil
}

var baffle, number bool
result := &strings.Builder{}
smbRep := &strings.Builder{}

if unicode.IsDigit(rune(v[0])) {
return "", ErrInvalidString
}

for _, currRune := range v {
if err := check(&baffle, &number, currRune, result, smbRep); err != nil {
return "", err
}
}

if baffle {
return result.String(), ErrInvalidString
}

result.WriteString(smbRep.String())
return result.String(), nil
}

func check(baffle, number *bool, currRune rune, result, smbRep *strings.Builder) error {
if currRune == '\\' {
*number = false
if *baffle {
if smbRep.Len() == 0 {
smbRep.WriteRune('\\')
*baffle = false
return nil
}
result.WriteString(smbRep.String())
smbRep.Reset()
return nil
}
*baffle = true
return nil
}

if num, err := strconv.Atoi(string(currRune)); err == nil {
if *number {
return ErrInvalidString
}

if *baffle {
smbRep.WriteRune(currRune)
*baffle = false
return nil
}

*number = true
if smbRep.Len() == 0 {
buf := result.String()
result.Reset()
result.WriteString(buf[:len(buf)-1])
smbRep.WriteRune(rune(buf[len(buf)-1]))
}

*baffle = false
if num != 0 {
result.WriteString(strings.Repeat(smbRep.String(), num))
}
smbRep.Reset()
return nil
}

if *baffle {
if smbRep.Len() == 0 {
smbRep.WriteRune('\\')
*baffle = false
}

smbRep.WriteRune(currRune)
return nil
}

result.WriteRune(currRune)
*number = false
return nil
}
10 changes: 6 additions & 4 deletions hw02_unpack_string/unpack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,18 @@ func TestUnpack(t *testing.T) {
{input: "", expected: ""},
{input: "aaa0b", expected: "aab"},
// uncomment if task with asterisk completed
// {input: `qwe\4\5`, expected: `qwe45`},
// {input: `qwe\45`, expected: `qwe44444`},
// {input: `qwe\\5`, expected: `qwe\\\\\`},
// {input: `qwe\\\3`, expected: `qwe\3`},
{input: `qwe\4\5`, expected: `qwe45`},
{input: `qwe\45`, expected: `qwe44444`},
{input: `qwe\\5`, expected: `qwe\\\\\`},
{input: `qwe\\\3`, expected: `qwe\3`},
{input: `d\n5abc`, expected: `d\n\n\n\n\nabc`},
}

for _, tc := range tests {
tc := tc
t.Run(tc.input, func(t *testing.T) {
result, err := Unpack(tc.input)
t.Log(result, err)
require.NoError(t, err)
require.Equal(t, tc.expected, result)
})
Expand Down