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