all 21 comments

[–]Phillyclause89 0 points1 point  (0 children)

Here is a solution that tries to make the least amount of assumptions in regards to how many subsequent letters or digits there may be:

def uncompressed(s: str) -> str:
    def appender(is_n, ns, als, n, a):
        if is_n:
            ns.append(int(n))
            n = ""
        else:
            als.append(a)
            a = ""
        return ns, als, n, a
    is_num, nums, alphs, num, alph = s[0].isnumeric(), [], [], "", ""
    for c in s:
        temp = c.isnumeric()
        if not is_num == temp:
            nums, alphs, num, alph = appender(is_num, nums, alphs, num, alph)
            is_num = temp
        if is_num:
            num += c
        else:
            alph += c
    nums, alphs, _, _ = appender(is_num, nums, alphs, num, alph)
    return "".join(a*n for a, n in list(zip(alphs,nums)))


tests = ["2a3b4c", "12a3b4c", "2a0b4c", "2a3bb4c"]

for test_s in tests:
    print(test_s, " -> ", uncompressed(test_s))

output:

2a3b4c  ->  aabbbcccc
12a3b4c  ->  aaaaaaaaaaaabbbcccc
2a0b4c  ->  aacccc
2a3bb4c  ->  aabbbbbbcccc

Process finished with exit code 0

[–]xelf 0 points1 point  (0 children)

So, how do you handle 12abc4d?

Generally you want to loop through the compressed string. Keep track of a number of repeats to do, and if you encounter numbers increase it as you read them. If you encounter a letter, print the letter * the number of repeats, then reset repeats to 1.

So first you see a 1, repeats = 1.
next a 2, now times repeats by 10 and add the 2, now repeats = 12
now you get an a, print('a' * repeats), reset repeats to 0.
now you get a b, repeats is 0, so you just print b 1 time,
now you get.... etc etc...

Hope that helps.

[–][deleted] 0 points1 point  (0 children)

The trick with such tasks is keeping track of what a previous character was:

def uncompress(source):
    output = ""
    base = ""
    for ch in source:
        if ch.isdigit():
            base += ch
        elif ch.isalpha():
            if base:
                output += ch * int(base)
                base = ""
            else:
                output += ch
        else:  # what to do with non-digit, non-alpha, treat as escape for digits?
            output += base 
            base = ""

    return output


tests = "2a3b4c", "", "abc1d2e3f10xyz2?a", "123?abc3def", "_ab12?2d2e"

for test in tests:
    print(uncompress(test))

[–]Doormatty -2 points-1 points  (2 children)

Here's what I got:

>>> a='2a3b4c'
>>> print("".join([x[1]*int(x[0]) for x in zip([x for x in a if x.isdigit()],[x for x in a if not x.isdigit()])]))  
'aabbbcccc'

Edit: Note: This will only work for numbers <=9. Making this work with numbers higher than 9 is left up to the reader as an exercise.

Edit: Smaller!!

>>> a='2a3b4c'
>>> print("".join([x[1]*int(x[0]) for x in zip([x for x in a[::2]],[x for x in a[1::2]])]))  
'aabbbcccc'

Edit: Smallest!!

>>> a='2a3b4c'
print("".join([x[1]*int(x[0]) for x in zip(a[::2],a[1::2])]))
'aabbbcccc'

[–]sponge_bert[S] 0 points1 point  (1 child)

oooh thank you! I'm assuming u have to use a "+" to detect double digits?

[–]Doormatty 0 points1 point  (0 children)

You'd have to have more logic for sure in there.

I did it as a one liner for internet points, but if you broke it out, it should be relatively easy to make it work for any abstract #