Этот пост изначально появился на steadbytes.com.
Полное решение можно найти на Гадость
Часть первая
Учитывая Ввод головоломки Содержащие строковое представление полимера, используемого в костюме Санты, нас просят найти Сколько устройств остаются после полного взаимодействия полимера Отказ Нам говорят, что реакции происходят между соседний Единицы того же Тип Но напротив Полярность :
- Тип
- Полярность /нижний регистр
aA -> reaction ab -> no reaction aB -> no reaction aa -> no reaction
Когда пара соседних единиц реагирует, они разрушаются, которые могут затем создавать другую реакцию на пару подразделений, которые теперь примыкаются, например:
abBAbA -> aAbA -> bA
Расставание ввода
Это простой случай чтения во всем введении в виде одной строки:
with open("input.txt") as f: polymer = f.read().strip() # remove leading/trailing whitespace just in case
Имитация реакции
Полная реакция может быть смоделирована с использованием A стек Чтобы удерживать подразделения полимера в виде реакции:
- Инициализируйте пустой стек
- Для каждого блока в полимере:
- Если устройство не вызывает реакции, нажмите ее на стек
- Остальное, поп-предыдущий агрегат от стека (уничтожить пару)
- Единицы, остающиеся в стеке, представляют собой полностью отреагировавший полимер
Пара подразделений реагирует, если они одинаковы и противоположная полярность. Эти отношения могут быть представлены с использованием словаря, который отображает отображение каждого возможного блока к соответствующему реакционному блоку:
import string unit_pairs_map = { **{ch: ch.upper() for ch in string.ascii_lowercase}, **{ch: ch.lower() for ch in string.ascii_uppercase}, }
Учитывая полимерное устройство, требуемый соседний агрегат для реакции на проведение, можно найти, глядя его в Unit_pairs_map
:
# find required adjacent unit for 'a' unit_pairs_map['a'] # A # find required adjacent unit for 'A' unit_pairs_map['A'] # a
Алгоритм выше теперь может быть реализован:
def part_1(polymer): stack = [] for unit in polymer: # there is a previous unit and it reacts with the current unit if stack and unit == unit_pairs_map[stack[-1]]: # reaction -> destroy the units stack.pop() else: # no reaction -> unit remains stack.append(unit) return len(stack)
Для моей ввода головоломки результат – 10496 Отказ
Часть вторая
Далее нам говорят, что более полная реакция может быть уменьшена, если определенный тип полимера удален. Нас просят найти Длина кратчайшего Возможный полимер, удаляя все единицы ровно одного типа и полностью реагируя результатом.
- Для каждого возможного типа единицы
- Удалите все вхождения устройства из исходного полимера
- Полностью реагировать полимер
- Измерить длину реагированного полимера
- Вернуть кратчайшую длину
Подзадачи для шага 1 алгоритма на самом деле такие же, как часть 1 головоломки. Сохранить Вещи сухие, эта логика может быть извлечена из part_1
Функция:
def react_polymer(polymer): # reaction logic from part 1 stack = [] for unit in polymer: if stack and unit == unit_pairs_map[stack[-1]]: stack.pop() else: stack.append(unit) return stack def part_1(polymer): return len(react_polymer(polymer))
Решение до части двух теперь может использовать rage_polymer
Функция для подзаправки шага 1 В алгоритме:
def part_2(polymer): # original polymer length is the shortest so far best = len(polymer) for ch in string.ascii_lowercase: # unit types = letters of the alphabet reacted_polymer = react_polymer( # remove all occurrences (both polarities) [u for u in polymer if u != ch and u != ch.upper()] ) # keep track of the shortest polymer found so far best = min(best, len(reacted_polymer)) return best
Для моей ввода головоломки результат – 5774 Отказ
Ресурсы
– Использование списков Python в виде стеков
Оригинал: “https://dev.to/steadbytes/aoc-2018-day-5-alchemical-reduction-1beg”