Part 1
In this puzzle we are asked to find the length of a string after a custom decompression algorithm. The string has markers in the form of (aXb) which state the next a characters should be repeated b times.
We are only interested in the length, so we only keep track of the decompressed string. We iterate over the string from start to end and keep the current position in a variable. At each position we check via whether we are at the start of a marker. If not, we can increase the length by one and go a single position forward. If the next characters are a marker, we parse it and increase the length by a*b and skip over the marker and the repeated characters.
current_index = 0
length = 0
while current_index < len(line):
if m := re.match(r"^\((\d+)x(\d+)\)", line[current_index:]):
group_length = int(m.group(1))
group_repeats = int(m.group(2))
length += group_length * group_repeats
current_index += len(m.group(0)) + group_length
else:
length += 1
current_index += 1
return length
Part 2
In part 2, the decompressing algorithm got more complicated. If there are markers in repeated text, we should also interpret them as markers.
We can handle this recursive repetition when we find a marker. Instead of increasing the length by a, we recursively call our decompressing algorithm on the repeated characters. After they are decompressed, they return a length, which we then multiply with our repeats.
def part_2(line):
current_index = 0
length = 0
while current_index < len(line):
if m := re.match(r"^\((\d+)x(\d+)\)", line[current_index:]):
group_length = int(m.group(1))
group_repeats = int(m.group(2))
before_group_index = current_index + len(m.group(0))
length += part_2(line[before_group_index: before_group_index + group_length]) * group_repeats
current_index += len(m.group(0)) + group_length
else:
length += 1
current_index += 1
return length
No comments:
Post a Comment