Solution to problem 5 in Python
This commit is contained in:
parent
b7d0679c45
commit
6b8e82ed78
123
src/Year_2018/P5.py
Normal file
123
src/Year_2018/P5.py
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
# --- Day 5: Alchemical Reduction ---
|
||||||
|
|
||||||
|
# You've managed to sneak in to the prototype suit manufacturing lab. The Elves
|
||||||
|
# are making decent progress, but are still struggling with the suit's size
|
||||||
|
# reduction capabilities.
|
||||||
|
|
||||||
|
# While the very latest in 1518 alchemical technology might have solved their
|
||||||
|
# problem eventually, you can do better. You scan the chemical composition of
|
||||||
|
# the suit's material and discover that it is formed by extremely long polymers
|
||||||
|
# (one of which is available as your puzzle input).
|
||||||
|
|
||||||
|
# The polymer is formed by smaller units which, when triggered, react with each
|
||||||
|
# other such that two adjacent units of the same type and opposite polarity are
|
||||||
|
# destroyed. Units' types are represented by letters; units' polarity is
|
||||||
|
# represented by capitalization. For instance, r and R are units with the same
|
||||||
|
# type but opposite polarity, whereas r and s are entirely different types and
|
||||||
|
# do not react.
|
||||||
|
|
||||||
|
# For example:
|
||||||
|
|
||||||
|
# In aA, a and A react, leaving nothing behind.
|
||||||
|
# In abBA, bB destroys itself, leaving aA. As above, this then destroys
|
||||||
|
# itself, leaving nothing.
|
||||||
|
# In abAB, no two adjacent units are of the same type, and so nothing
|
||||||
|
# happens.
|
||||||
|
# In aabAAB, even though aa and AA are of the same type, their polarities
|
||||||
|
# match, and so nothing happens.
|
||||||
|
|
||||||
|
# Now, consider a larger example, dabAcCaCBAcCcaDA:
|
||||||
|
|
||||||
|
# dabAcCaCBAcCcaDA The first 'cC' is removed.
|
||||||
|
# dabAaCBAcCcaDA This creates 'Aa', which is removed.
|
||||||
|
# dabCBAcCcaDA Either 'cC' or 'Cc' are removed (the result is the same).
|
||||||
|
# dabCBAcaDA No further actions can be taken.
|
||||||
|
|
||||||
|
# After all possible reactions, the resulting polymer contains 10 units.
|
||||||
|
|
||||||
|
# How many units remain after fully reacting the polymer you scanned? (Note:
|
||||||
|
# in this puzzle and others, the input is large; if you copy/paste your input,
|
||||||
|
# make sure you get the whole thing.)
|
||||||
|
|
||||||
|
import re
|
||||||
|
from copy import copy
|
||||||
|
from string import ascii_lowercase
|
||||||
|
|
||||||
|
with open("files/P5.txt") as f:
|
||||||
|
polymer = [line for line in f.read().split()][0]
|
||||||
|
|
||||||
|
|
||||||
|
def react(s: str) -> bool:
|
||||||
|
return abs(ord(s[0]) - ord(s[1])) == 32
|
||||||
|
|
||||||
|
|
||||||
|
def remove_substring(substr: str, s: str) -> str:
|
||||||
|
return re.sub(substr, "", s)
|
||||||
|
|
||||||
|
|
||||||
|
def part_1() -> None:
|
||||||
|
sequence = copy(polymer)
|
||||||
|
idx = 0
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
pair = "".join((sequence[idx], sequence[idx + 1]))
|
||||||
|
if react(pair):
|
||||||
|
sequence = remove_substring(pair, sequence)
|
||||||
|
idx = 0
|
||||||
|
else:
|
||||||
|
idx += 1
|
||||||
|
except IndexError:
|
||||||
|
break
|
||||||
|
print(f"There are {len(sequence)} units remaining")
|
||||||
|
|
||||||
|
|
||||||
|
# --- Part Two ---
|
||||||
|
|
||||||
|
# Time to improve the polymer.
|
||||||
|
|
||||||
|
# One of the unit types is causing problems; it's preventing the polymer from
|
||||||
|
# collapsing as much as it should. Your goal is to figure out which unit type
|
||||||
|
# is causing the most problems, remove all instances of it (regardless of
|
||||||
|
# polarity), fully react the remaining polymer, and measure its length.
|
||||||
|
|
||||||
|
# For example, again using the polymer dabAcCaCBAcCcaDA from above:
|
||||||
|
|
||||||
|
# Removing all A/a units produces dbcCCBcCcD. Fully reacting this polymer
|
||||||
|
# produces dbCBcD, which has length 6.
|
||||||
|
# Removing all B/b units produces daAcCaCAcCcaDA. Fully reacting this
|
||||||
|
# polymer produces daCAcaDA, which has length 8.
|
||||||
|
# Removing all C/c units produces dabAaBAaDA. Fully reacting this polymer
|
||||||
|
# produces daDA, which has length 4.
|
||||||
|
# Removing all D/d units produces abAcCaCBAcCcaA. Fully reacting this
|
||||||
|
# polymer produces abCBAc, which has length 6.
|
||||||
|
|
||||||
|
# In this example, removing all C/c units was best, producing the answer 4.
|
||||||
|
|
||||||
|
# What is the length of the shortest polymer you can produce by removing all
|
||||||
|
# units of exactly one type and fully reacting the result?
|
||||||
|
|
||||||
|
|
||||||
|
def part_2() -> None:
|
||||||
|
lengths = []
|
||||||
|
for char in ascii_lowercase:
|
||||||
|
sequence = copy(polymer)
|
||||||
|
sequence = sequence.replace(char, "").replace(char.upper(), "")
|
||||||
|
idx = 0
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
pair = "".join((sequence[idx], sequence[idx + 1]))
|
||||||
|
if react(pair):
|
||||||
|
sequence = remove_substring(pair, sequence)
|
||||||
|
idx = 0
|
||||||
|
else:
|
||||||
|
idx += 1
|
||||||
|
except IndexError:
|
||||||
|
break
|
||||||
|
lengths.append(len(sequence))
|
||||||
|
|
||||||
|
print(f"The length of the shortest polymer is {min(lengths)}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
part_1()
|
||||||
|
part_2()
|
Loading…
Reference in New Issue
Block a user