Skip to content

Commit

Permalink
Merge pull request #2 from timersha/hw02_unpack_string
Browse files Browse the repository at this point in the history
HW2 is completed
  • Loading branch information
timersha authored Jan 1, 2025
2 parents 5e1ffa6 + 324200a commit da3bb9d
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 18 deletions.
16 changes: 16 additions & 0 deletions hw02_unpack_string/.golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
linters-settings:
depguard:
rules:
Main:
files:
- $all
- "!$test"
allow:
- $gostd
- github.com/stretchr/testify/require
Test:
files:
- $test
allow:
- $gostd
- github.com/stretchr/testify
Empty file removed hw02_unpack_string/.sync
Empty file.
8 changes: 4 additions & 4 deletions hw02_unpack_string/go.mod
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
module github.com/fixme_my_friend/hw02_unpack_string
module github.com/timersha/golang-tests/hw02_unpack_string

go 1.22
go 1.22.0

require github.com/stretchr/testify v1.7.0
require github.com/stretchr/testify v1.10.0

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
11 changes: 4 additions & 7 deletions hw02_unpack_string/go.sum
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
99 changes: 96 additions & 3 deletions hw02_unpack_string/unpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,104 @@ package hw02unpackstring

import (
"errors"
"fmt"
"math"
"strconv"
"unicode"
"unicode/utf8"
)

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

func Unpack(_ string) (string, error) {
// Place your code here.
return "", nil
func Unpack(str string) (string, error) {
inputIndex := 0
resultIndex := 0
backslash := '\\'
input := []rune(str)
result := make([]rune, 0, 200)
inputLen := len(input) - 1

// validate length
if utf8.RuneCountInString(string(input)) == 0 {
return "", nil
}

// starts with digit
if unicode.IsDigit(input[0]) {
return "", ErrInvalidString
}

for inputIndex <= inputLen {
r := input[inputIndex]

inputNextIndex := nextIndex(&input, inputIndex)
nextR := input[inputNextIndex]
// finds number
if inputLen != inputNextIndex && unicode.IsDigit(r) && unicode.IsDigit(nextR) {
fmt.Println("finds number")
return "", ErrInvalidString
}

// escaped symbol is valid
isValidForEscape := unicode.IsDigit(nextR) || nextR == backslash
if r == backslash && isValidForEscape {
result = append(result, nextR)
resultIndex++
inputIndex += 2
continue
}

// escaped symbol is not valid
if r == backslash && !isValidForEscape {
fmt.Println("escaped symbol is not valid")
return "", ErrInvalidString
}

// repeatedly add rune
isDigit := unicode.IsDigit(r)
if isDigit {
shift := appendRune(&result, result[previousIndex(&result, resultIndex)], r)
resultIndex += shift
inputIndex++
continue
}

// remove current rune
vl, err := strconv.Atoi(string(nextR))
if err == nil && vl == 0 {
inputIndex++
continue
}

// simple append
result = append(result, r)
resultIndex++
inputIndex++
}

return string(result), nil
}

func appendRune(res *[]rune, rn rune, count rune) int {
value, err := strconv.Atoi(string(count))
if err != nil {
return 0
}

for range value - 1 {
*res = append(*res, rn)
}
return value
}

func nextIndex(sl *[]rune, index int) int {
slLen := math.Max(0, float64(len(*sl)-1))
nextIndex := index + 1
return int(math.Min(float64(slLen), float64(nextIndex)))
}

func previousIndex(sl *[]rune, index int) int {
slLen := math.Max(0, float64(len(*sl)-1))
previousIndex := index - 1
return int(math.Min(float64(slLen), math.Max(0, float64(previousIndex))))
}
8 changes: 4 additions & 4 deletions hw02_unpack_string/unpack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ 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`},
}

for _, tc := range tests {
Expand Down

0 comments on commit da3bb9d

Please sign in to comment.