Search code examples
swiftrun-length-encoding

Task from the interview. How we would solve it?


Convert String in this way

let initialString = "atttbcdddd"
// result must be like this "at3bcd4"

But repetition must be more than 2. For example, if we have "aa" the result will be "aa", but if we have "aaa", the result will be "a3"

One more example:

let str = "aahhhgggg"
//result "aah3g4"

My try:

func encrypt(_ str: String) -> String {

    let char = str.components(separatedBy: "t") //must input the character
    var count = char.count - 1
    var string = ""
    string.append("t\(count)")
    return string
}

if i input "ttttt" it will return "t5" but i should input the character


Solution

  • What you are looking for is the “Run-length encoding”. Note that this is not an encryption!

    Here is a possible implementation (explanations inline):

    func runLengthEncode(_ str: String) -> String {
        var result = ""
        var pos = str.startIndex // Start index of current run
        while pos != str.endIndex {
            let char = str[pos]
            // Find index of next run (or `endIndex` if there is none):
            let next = str[pos...].firstIndex(where: { $0 != char }) ?? str.endIndex
            // Compute the length of the current run:
            let length = str.distance(from: pos, to: next)
            // Append compressed output to the result:
            result.append(length <= 2 ? String(repeating: char, count: length) : "\(char)\(length)")
            pos = next // ... and continue with next run
        }
        return result
    }
    

    Examples:

    print(runLengthEncode("atttbcdddd")) // at3bcd4
    print(runLengthEncode("aahhhgggg"))  // aah3g4
    print(runLengthEncode("abbbaaa"))    // ab3a3