#358 · Codes and ciphers · Advanced · 125 XP · about 25 min
LZW compression replaces repeated phrases with numbers from a dictionary that it builds while it reads, so the dictionary itself never has to be sent: the reader can rebuild it. Write lzw_compress(text, max_size=4096) that returns the codes LZW produces for text, in order, as a list of integers.
The dictionary maps strings to codes. It starts with the 256 one-character strings: chr(i) has code i, for i from 0 to 255. Then, until the whole text is used:
The dictionary may hold at most max_size entries in total, the 256 starting ones included. Once it is full, nothing more is added, and compression carries on with the entries it already has. The empty text gives an empty list.
lzw_compress("ABABABA") # returns [65, 66, 256, 258] lzw_compress("aaaa") # returns [97, 256, 97] lzw_compress("ABABABA", 257) # returns [65, 66, 256, 256, 65]
In the first example: A is output (65) and AB gets code 256; B is output (66) and BA gets 257; AB is output (256) and ABA gets 258; ABA is the rest of the text and is output (258). In the last example there is room for only one new entry, AB.
text has 0 to 100,000 characters, each with a code below 256.256 <= max_size <= 100,000First solves only, ranked by stars and then time.