Рубрики
Без рубрики

AOC 2018 день 5: Алхимическое снижение

Представляем эльфы в полимерную машину. Помечено AC2018, Python, Puzzle, Challenge.

Этот пост изначально появился на 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 стек Чтобы удерживать подразделения полимера в виде реакции:

  1. Инициализируйте пустой стек
  2. Для каждого блока в полимере:
    • Если устройство не вызывает реакции, нажмите ее на стек
    • Остальное, поп-предыдущий агрегат от стека (уничтожить пару)
  3. Единицы, остающиеся в стеке, представляют собой полностью отреагировавший полимер

Пара подразделений реагирует, если они одинаковы и противоположная полярность. Эти отношения могут быть представлены с использованием словаря, который отображает отображение каждого возможного блока к соответствующему реакционному блоку:

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. Для каждого возможного типа единицы
    • Удалите все вхождения устройства из исходного полимера
    • Полностью реагировать полимер
    • Измерить длину реагированного полимера
  2. Вернуть кратчайшую длину

Подзадачи для шага 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”