How to Repeat by String Index in Golang


The challenge

Create a function that repeats each character by the amount of it’s index value of the original string.

Examples:

accum("abcd") -> "A-Bb-Ccc-Dddd"
accum("RqaEzty") -> "R-Qq-Aaa-Eeee-Zzzzz-Tttttt-Yyyyyyy"
accum("cwAt") -> "C-Ww-Aaa-Tttt"

The parameter of accum is a string that includes only letters from a..z and A..Z.

The solution in Golang

Option 1:

package solution

import "strings"

func Accum(s string) string {
    words := make([]string, len(s))
    
    for i, c := range s {
        words[i] = strings.Title(strings.Repeat(strings.ToLower(string(c)), i+1))
    }
   
    return strings.Join(words, "-")
}

Option 2:

package solution

import "unicode"

func Accum(s string) string {
    res := ""
    for i, r := range s {
        if i != 0 {
            res += "-"
        }
        res += string(unicode.ToTitle(r))
        for j := 0; j < i; j++ {
            res += string(unicode.ToLower(r))
        }
    }
    return res
}

Option 3:

package solution

import "strings"

func Accum(s string) string {
    var b strings.Builder
    for i, v := range s {
      b.WriteString(strings.ToUpper(string(v)))
      b.WriteString(strings.Repeat(strings.ToLower(string(v)), i))
      if (i < len(s) - 1) {
        b.WriteString("-")
      }
    }
    return b.String()
}

Test cases to validate our solution

package test
import (
  . "github.com/onsi/ginkgo"
  . "github.com/onsi/gomega"
  . "our/solution"
  "math/rand"
  "time"
  "bytes"
)

func dotest(s string, exp string) {
    var ans = Accum(s)
    Expect(ans).To(Equal(exp))
}

func accumOCE(s string) string {
    a := bytes.ToLower([]byte(s))
    var res []byte
    for i := 0; i < len(a); i++ {
        t := bytes.Title(bytes.Repeat(a[i:i+1], i + 1))
        res = append(res, t...)
        res = append(res, "-"...)
    }
    return string(res[:len(res) -1])
}
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
func randStringBytes(n int) string {
    b := make([]byte, n)
    for i := range b {
        b[i] = letterBytes[rand.Intn(len(letterBytes))]
    }
    return string(b)
}
func random(min, max int) int {
    return rand.Intn(max - min) + min
}
func randomdotest() {
    rand.Seed(time.Now().UTC().UnixNano())
    for i := 0; i < 50 ; i++ {        
        n := random(5, 12)
        s := randStringBytes(n)
        sol := accumOCE(s)
        dotest(s, sol)
    }
}

var _ = Describe("Test Example", func() {

    It("should handle basic cases", func() {
        dotest("ZpglnRxqenU", "Z-Pp-Ggg-Llll-Nnnnn-Rrrrrr-Xxxxxxx-Qqqqqqqq-Eeeeeeeee-Nnnnnnnnnn-Uuuuuuuuuuu")
        dotest("NyffsGeyylB", "N-Yy-Fff-Ffff-Sssss-Gggggg-Eeeeeee-Yyyyyyyy-Yyyyyyyyy-Llllllllll-Bbbbbbbbbbb")
        dotest("MjtkuBovqrU", "M-Jj-Ttt-Kkkk-Uuuuu-Bbbbbb-Ooooooo-Vvvvvvvv-Qqqqqqqqq-Rrrrrrrrrr-Uuuuuuuuuuu")
        dotest("EvidjUnokmM", "E-Vv-Iii-Dddd-Jjjjj-Uuuuuu-Nnnnnnn-Oooooooo-Kkkkkkkkk-Mmmmmmmmmm-Mmmmmmmmmmm")
        dotest("HbideVbxncC", "H-Bb-Iii-Dddd-Eeeee-Vvvvvv-Bbbbbbb-Xxxxxxxx-Nnnnnnnnn-Cccccccccc-Ccccccccccc")
        dotest("VwhvtHtrxfE", "V-Ww-Hhh-Vvvv-Ttttt-Hhhhhh-Ttttttt-Rrrrrrrr-Xxxxxxxxx-Ffffffffff-Eeeeeeeeeee")
        dotest("KurgiKmkphY", "K-Uu-Rrr-Gggg-Iiiii-Kkkkkk-Mmmmmmm-Kkkkkkkk-Ppppppppp-Hhhhhhhhhh-Yyyyyyyyyyy")
        dotest("NctlfBlnmfH", "N-Cc-Ttt-Llll-Fffff-Bbbbbb-Lllllll-Nnnnnnnn-Mmmmmmmmm-Ffffffffff-Hhhhhhhhhhh")
        dotest("WegunHvbdmV", "W-Ee-Ggg-Uuuu-Nnnnn-Hhhhhh-Vvvvvvv-Bbbbbbbb-Ddddddddd-Mmmmmmmmmm-Vvvvvvvvvvv")
        dotest("VoywwSpqidE", "V-Oo-Yyy-Wwww-Wwwww-Ssssss-Ppppppp-Qqqqqqqq-Iiiiiiiii-Dddddddddd-Eeeeeeeeeee")
        dotest("VbaixFpxdcO", "V-Bb-Aaa-Iiii-Xxxxx-Ffffff-Ppppppp-Xxxxxxxx-Ddddddddd-Cccccccccc-Ooooooooooo")
        dotest("OlyqvYwkuzF", "O-Ll-Yyy-Qqqq-Vvvvv-Yyyyyy-Wwwwwww-Kkkkkkkk-Uuuuuuuuu-Zzzzzzzzzz-Fffffffffff")
        dotest("JrhfdMtchiH", "J-Rr-Hhh-Ffff-Ddddd-Mmmmmm-Ttttttt-Cccccccc-Hhhhhhhhh-Iiiiiiiiii-Hhhhhhhhhhh")
        dotest("JiwpcSwslvW", "J-Ii-Www-Pppp-Ccccc-Ssssss-Wwwwwww-Ssssssss-Lllllllll-Vvvvvvvvvv-Wwwwwwwwwww")
        dotest("EagpiEvmabJ", "E-Aa-Ggg-Pppp-Iiiii-Eeeeee-Vvvvvvv-Mmmmmmmm-Aaaaaaaaa-Bbbbbbbbbb-Jjjjjjjjjjj")
        dotest("RznlcEmuxxP", "R-Zz-Nnn-Llll-Ccccc-Eeeeee-Mmmmmmm-Uuuuuuuu-Xxxxxxxxx-Xxxxxxxxxx-Ppppppppppp")
        dotest("OrggaExarzP", "O-Rr-Ggg-Gggg-Aaaaa-Eeeeee-Xxxxxxx-Aaaaaaaa-Rrrrrrrrr-Zzzzzzzzzz-Ppppppppppp")
        dotest("DriraMtedfB", "D-Rr-Iii-Rrrr-Aaaaa-Mmmmmm-Ttttttt-Eeeeeeee-Ddddddddd-Ffffffffff-Bbbbbbbbbbb")
        dotest("BjxseRxgtjT", "B-Jj-Xxx-Ssss-Eeeee-Rrrrrr-Xxxxxxx-Gggggggg-Ttttttttt-Jjjjjjjjjj-Ttttttttttt")
        dotest("EquhxOswchE", "E-Qq-Uuu-Hhhh-Xxxxx-Oooooo-Sssssss-Wwwwwwww-Ccccccccc-Hhhhhhhhhh-Eeeeeeeeeee")
    })
    It("should handle random cases", func() {
        randomdotest()
    })
})