Advent of Code 2015 — День 2

[Серия постов о том, как я решаю каждую из задач Advent of Code (AoC) с 2015 года по сегодняшний день на языке Python. День 1 вы можете найти здесь].

Головоломки в AoC должны быть легкомысленными, это касается и названий. Однако иногда они могут дать вам подсказку о том, что вас ждет. Вот часть 1 сегодняшней головоломки:

Хорошей строковой функцией, которая может пригодиться здесь, является split(), которая делит строку на список, основываясь на разделителе. Например, при делении '2x3x4' на 'x' получается список из трех элементов: ['2', '3', '4'].

К сожалению, все они являются строками, что будет немного неприятно, когда мы попытаемся их перемножить. К счастью, в Python есть функция map(), которая может применять функции к итераторам, включая списки. В итоге мы получаем что-то вроде этого:

l, w, h = map(int, data.split('x'))
Войти в полноэкранный режим Выйти из полноэкранного режима

Это подчеркивает еще одну замечательную особенность Python — возможность инициализировать или обновлять несколько переменных одновременно.

Следующая часть решения головоломки заключается в нахождении двух наименьших сторон, чтобы определить размер дополнительного листа оберточной бумаги. В Python есть min(), но это не помогает найти вторую наименьшую сторону. В конце концов, я решил отсортировать список так, чтобы первые два элемента всегда были самыми короткими. Позже я увидел, что min() используется в других решениях для нахождения наименьшего «лишнего» куска: extra_piece = min(l*w, w*h, 1*h).

Мой код, однако, по существу выглядел следующим образом:

total_area = 0
for box in data:

    l, w, h = sorted(map(int, box.split('x')))
    area = (2 * l * w) + (2 * l * h) + (2 * w * h)
    extra = l * w  #Always the shortest sides, thanks to the sort
    total_area += (area + extra)
Войти в полноэкранный режим Выход из полноэкранного режима

Это хорошо решило проблему первой части и сделало вторую часть на удивление простой:

Вычисления для части ленты также зависят от знания двух кратчайших сторон, что означает, что мой код части 1 можно просто расширить для решения части 2:

total_ribbon = 0
total_area = 0
for box in data:

    l, w, h = sorted(map(int, box.split('x')))

    area = (2 * l * w) + (2 * l * h) + (2 * w * h)
    extra = l * w
    total_area += (area + extra)

    bow = l * w * h
    ribbon = (2 * l) + (2 * w)
    total_ribbon += (bow + ribbon)
Войти в полноэкранный режим Выйти из полноэкранного режима

Я не видел ни одного решения для гольфа в Python, хотя было несколько для других языков, таких как PHP и Bash.

СОВЕТ Всегда пытайтесь угадать, какой будет часть 2!

Я уже сбился со счета, сколько раз мне приходилось полностью пересматривать свой подход к адвент-коду при появлении второй части! Часто этого можно избежать, если не бросаться с головой в решение первой части, не потратив минуту-другую на то, чтобы поразмышлять о том, как может развиваться головоломка. (Конечно, не делайте этого, если вы пытаетесь попасть в таблицу лидеров!)

Например, если в первой части головоломки вам нужно найти путь через поле данных, используя кардинальные направления, вы можете почти гарантировать, что во второй части вам придется двигаться по диагонали. Вы не сэкономите время на первой части, но вы можете сэкономить кучу времени на второй части, если спланируете все заранее. Это не всегда сработает, но чем больше головоломок вы сделаете, тем лучше вы будете чувствовать, что вас ждет впереди!

Переходим к третьему дню…

Оцените статью
devanswers.ru
Добавить комментарий