0

I have a problem decoding. First the string '44444' get encoded to '54'. (5 times 4) Now when I want to decode '54' its empty. (It does function with letters)

The algorithm decodes the string '4a3b2c' to 'aaaabbbcc'. Now when I want to decode '4a54' it just gives 'aaaa' but the right decoding is 'aaaa44444'. How can I decode this?

Here is the code:

def decode_RLE(x):
    decode = ''
    count = ''
    for i in x:
        
        if i.isdigit():
            #append to count
            count += i
        else i: 
   
            decode += i * int(count)
            count = '' 
         
    return decode
Red
  • 26,798
  • 7
  • 36
  • 58
  • 1
    you never reach your else. on the first iteration of the for loop i is 5, this is a digit to its append to count. ON the next iteration of your for loop i is 4 which is also a digit so its appended to count. Now there are no more elements in x so the loop finishes. And since you never entered the else decode will return empty – Chris Doyle Jan 28 '21 at 23:15
  • Well because "5" and "4" are both digits (`.isdigit()` would return True for both). So `54` in your case would not mean 5 x 4 (44444) but 54 x nothing. How do you distinguish between the numbers and actual encoded characters? – Yevhen Kuzmovych Jan 28 '21 at 23:15

4 Answers4

6

You can try string multiplication:

def decode(string):
    output = ''
    for i in range(0, len(string), 2):
        output += int(string[i]) * string[i + 1]
    return output

print(decode("54"))
print(decode("4a54"))

Output:

44444
aaaa44444

You can even use a list comprehension:

def decode(s):
    return ''.join(int(s[i]) * s[i + 1] for i in range(0, len(s), 2))
Red
  • 26,798
  • 7
  • 36
  • 58
2

That is due to the first if condition. After the loop you get count = "54" and decode = "". Then, the function return an empty string.

If the input has only two digits, technically the loop is not necessary. try this code:

def decode_RLE(x):
    return int(x[0])*x[1]

If the input has more than two digits, a loop and a good old fashioned slicing should work:

def decode_RLE(x):
    counts = x[0:len(x):2] #get odd digits
    chars = x[1:len(x):2] #get even digits
    decode = ""
    
    i = 0
    for ch in chars:
        decode += int(counts[i])*chars[i]
        i += 1
    
    return decode
Mata2907
  • 61
  • 7
1

By your logic, you only expect the one-digit lengths. If so you can iterate like so:

def decode_rle(x):
    decoded = ''
    iter_x = iter(x)
    for n, c in zip(iter_x, iter_x):
        decoded += c * int(n)
    return decoded

But this wouldn't work with two- or more-digit lengths

Yevhen Kuzmovych
  • 10,940
  • 7
  • 28
  • 48
0

A flag can fix this, telling the algorithm that the last passed character was a digit.

def decode_RLE(x):
    decode = ''
    count = ''
    was_digit = False
    for i in x:

        if was_digit:
            decode += i * int (count)
            count = ''
            was_digit = False
        
        if i.isdigit():
            count += i
            was_digit = True
         
    return decode
Dev Sony
  • 1
  • 3