В вымышленном 2D-мире набор инструкций 2D-печати для объекта может быть представлен в виде списка целых чисел следующим образом:
1 4 2 1 1 2 5 3 4
Каждое число представляет высоту объекта в этой конкретной точке. Приведенный выше список преобразуется в следующий объект при печати:
#
# # #
# ###
## ####
#########
Затем мы наполняем его как можно большим количеством воды, что приводит к следующему:
#
#~~~~#~#
#~~~~###
##~~####
#########
Мы определяем способность объекта быть единицами воды, которую объект может удерживать, когда он полностью заполнен; в этом случае 11.
Строго говоря, единица воды ( ~
) может существовать в месте, если и только если она окружена двумя сплошными блоками ( #
) в одной строке.
Вызов
Возьмите список положительных целых чисел в качестве входных данных (в любом формате) и выведите емкость объекта, напечатанного, когда список используется в качестве инструкций.
Можно предположить, что список содержит хотя бы один элемент, и все элементы находятся в диапазоне от 1 до 255.
Тестовые случаи
+-----------------+--------+
| Input | Output |
+-----------------+--------+
| 1 | 0 |
| 1 3 255 1 | 0 |
| 6 2 1 1 2 6 | 18 |
| 2 1 3 1 5 1 7 1 | 7 |
| 2 1 3 1 7 1 7 1 | 9 |
| 5 2 1 3 1 2 5 | 16 |
| 80 80 67 71 | 4 |
+-----------------+--------+
Ответы:
Haskell, 54 байта
Выражения
scanl1 max l
иscanr1 max l
вычисляют рабочий максимум списка, читающего вперед и назад, то есть профиль воды плюс земля, если вода будет течь в одном направлении.Orig:
Слева:
Правильно:
Тогда профиль общей картины является минимальным из них, что соответствует тому, где вода не течет ни в одном направлении.
Минимум:
Наконец, количество воды - это сумма этого списка, который содержит как воду, так и землю, за вычетом суммы исходного списка, который содержит только землю.
источник
Желе, 10 байт
Хотя для APL требуется несколько скобок и J двухсимвольных символов, алгоритм в Jelly прекрасен.
Попробуй это здесь .
источник
МАТЛ , 14
Мой ответ Matlab переведен на MATL. алгоритм xnor.
объяснение
Y>
:cummax()
(ввод неявно помещается в стек)G
: толчок ввода (снова)P
:flip()
Y>
:cummax()
P
:flip()
2$X<
:min([],[])
(минимум с двумя аргументами)G
: толчок ввода (снова)-
:-
s
:sum()
источник
Дьялог АПЛ, 17 байт
Это монадическая последовательность, которая принимает входной массив справа.
Алгоритм почти такой же, как у xnor, хотя я нашел его независимо. Он сканирует максимум в обоих направлениях (в обратном направлении, переворачивая массив, сканируя и снова переворачивая), и находит векторизованный минимум из них. Затем вычитается исходный массив и суммы.
Другой способ сделать это - разделить массив в каждом месте, но это дольше.
Попробуй это здесь .
источник
+/⊢-⍨⌈\⌊⌈\⍢⌽
.Матлаб, 47
Также используя алгоритм xnor.
источник
MATLAB,
116113109106 байтЭто работает, сохраняя верхнюю точку слева, и, перебирая каждую следующую точку, находит самую высокую точку справа. Если текущая точка меньше, чем обе верхние точки, то это добавляет минимальную разницу к совокупному объему.
Ungolfed код:
В первый раз, когда я пытался что-то сыграть в гольф, MATLAB, кажется, не лучший способ сделать это в ....
источник
ES6, 101 байт
Еще один порт алгоритма @ xnor.
источник
Python 2 , 68 байт
Попробуйте онлайн!
источник
Пип
-l
, 19 байтПринимает входные числа в качестве аргументов командной строки. Или добавьте
-r
флаг, чтобы они воспринимались как stdin: попробуйте онлайн!объяснение
В отличие от всех других ответов, в Пипе было на самом деле короче построить (измененную версию) ASCII-арт и сосчитать единицы воды.
Начнем с
g
списка аргументов.0Xg
создает список строк из n нулей для каждого n вg
.ZD1
затем объединяет эти строки в цепочку, используя1
для заполнения любых пробелов в результирующем прямоугольном вложенном списке:ST
преобразует этот список в строку В-l
флаг указывает , что списки отформатирован следующим образом : каждый вложенный список соединены без сепаратора, а на верхнем уровне разделителем является символ новой строки. Таким образом, мы получаем эту многострочную строку - по сути, диаграмму объекта, но вверх ногами:Затем мы найдем все совпадения регулярного выражения
`0.*0`
. Это соответствует двум самым внешним стенам и всему между ними на каждой линии.J
объединяет эти строки в одну большую строку и$+
суммирует ее, давая число1
s - равное количеству воды, которое может удерживать объект.источник