|
2 | 2 | Given a compressed string in which a number followed by [] indicate how many times those characters occur, decompress the string |
3 | 3 | Eg. : a3[b2[c1[d]]]e will be decompressed as abcdcdbcdcdbcdcde. |
4 | 4 | Assume the string is well formed and number will always be followed by a []. |
| 5 | + |
| 6 | +# SOLUTION |
| 7 | +Need to clarify what a2[b2[c]d2[e]]f would decompress to. I would assume to 'abccdeebccdeef'. |
| 8 | +``` |
| 9 | +import re |
| 10 | +
|
| 11 | +def decompress(compressed_string): |
| 12 | + tokens = re.split('([\[|\]])', compressed_string) |
| 13 | + tokens = [token for token in tokens if token != ''] # remove extra spaces |
| 14 | + if len(tokens) == 0: |
| 15 | + return '' |
| 16 | + token_stack = list() |
| 17 | + result_stack = list() |
| 18 | + # token_stack.append(tokens[0]) |
| 19 | + curr_token_index = 0 |
| 20 | + while curr_token_index < len(tokens): |
| 21 | + curr_token = tokens[curr_token_index] |
| 22 | + if curr_token == '[': |
| 23 | + curr_token_index += 1 |
| 24 | + next_token = tokens[curr_token_index] |
| 25 | + token_stack.append(next_token) |
| 26 | + elif curr_token == ']': |
| 27 | + next_result = get_next_result(token_stack, result_stack) |
| 28 | + result_stack.append(next_result) |
| 29 | + else: |
| 30 | + while len(token_stack): |
| 31 | + next_result = get_next_result(token_stack, result_stack) |
| 32 | + result_stack.append(next_result) |
| 33 | + token_stack.append(curr_token) |
| 34 | + result_stack.append('') |
| 35 | + curr_token_index += 1 |
| 36 | + while len(token_stack): |
| 37 | + next_result = get_next_result(token_stack, result_stack) |
| 38 | + result_stack.append(next_result) |
| 39 | + return ''.join(result_stack) |
| 40 | +
|
| 41 | +def get_next_result(token_stack, result_stack): |
| 42 | + if len(token_stack): |
| 43 | + token = token_stack.pop() |
| 44 | + top_result = '' |
| 45 | + if len(result_stack): |
| 46 | + top_result = result_stack.pop() |
| 47 | + word, n_dups = parse_token(token) |
| 48 | + new_result = '' |
| 49 | + for _ in range(n_dups): |
| 50 | + new_result += top_result |
| 51 | + new_result = word + new_result |
| 52 | + return new_result |
| 53 | + return '' |
| 54 | +
|
| 55 | +def parse_token(token): |
| 56 | + last_alpha_index = -1 |
| 57 | + for letter in token: |
| 58 | + if not letter.isdigit(): |
| 59 | + last_alpha_index += 1 |
| 60 | + word = token[0:last_alpha_index+1] |
| 61 | + number = 1 |
| 62 | + if last_alpha_index != len(token)-1: |
| 63 | + number = int(token[last_alpha_index+1:]) |
| 64 | + return word, number |
| 65 | +
|
| 66 | +string = 'a3[b2[c1[d]]]e' |
| 67 | +assert decompress(string) == 'abcdcdbcdcdbcdcde' |
| 68 | +
|
| 69 | +# string = 'a2[b2[c]d2[e]]f' |
| 70 | +# assert decompress(string) == 'abccdeebccdeef' |
| 71 | +``` |
0 commit comments