I want to get a program or a function to compress ASCII art from a text file into RLE with a run length of 2, so it counts the amount of characters and displays it like so:
I don't really see how your code is supposed to split the string into groups of 2+1 character, but anyway, using a dict
or OrderedDict
would not work, as even if ordered, a dict
can hold any key at most once, i.e. it could not represent an encoded string like 01a01b01a
. Instead, you should create a list of tuples, and you can do so using just string slicing and a range
with step=3
:
def runLengthEncoding(s):
return [(int(s[i:i+2]), s[i+2]) for i in range(0, len(s), 3)]
>>> runLengthEncoding("04662312x52c02z01 03a")
[(4, '6'), (62, '3'), (12, 'x'), (52, 'c'), (2, 'z'), (1, ' '), (3, 'a')]
It is not really clear from your question whether the function is supposed to encode or decode the strings, but judging from your final sentence, I assume you want to decode them. The other direction can easily be done with itertools.groupby
and some str.join
ing:
# RLE -> Text
s = "04662312x52c02z01 03a"
pairs = [(int(s[i:i+2]), s[i+2]) for i in range(0, len(s), 3)]
# [(4, '6'), (62, '3'), (12, 'x'), (52, 'c'), (2, 'z'), (1, ' '), (3, 'a')]
text = ''.join(n * c for n, c in pairs)
# '666633333333333333333333333333333333333333333333333333333333333333xxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccccccccccczz aaa'
# Text -> RLE
from itertools import groupby
pairs = [(len(list(g)), k) for k, g in groupby(text)]
# [(4, '6'), (62, '3'), (12, 'x'), (52, 'c'), (2, 'z'), (1, ' '), (3, 'a')]
s = ''.join("%02d%s" % (n, c) for n, c in pairs)
# '04662312x52c02z01 03a'