Введение
В этом задании в качестве входных данных вам дается ASCII-представление сети (развернутой поверхности) прямоугольного кубоида (3D-прямоугольника). Формат такой:
....+--+.......
....|##|.......
....|##|.......
....|##|.......
+---+--+---+--+
|###|##|###|##|
+---+--+---+--+
....|##|.......
....|##|.......
....|##|.......
....+--+.......
Каждая грань кубоида представляет собой прямоугольник из #
s, окруженный +-|
символами. Снаружи сеть заполнена с .
. Сеть всегда будет иметь одинаковую ориентацию: средняя грань окружена четырьмя соседними гранями, а аналог средней грани находится у правой границы ввода. Входные данные дополняются .
s до прямоугольной формы и не будут содержать лишних строк или столбцов .
s.
Задание
Ваша задача - взять в качестве входных данных диаграмму, описанную выше, и вычислить объем кубоида, который он представляет, который является просто произведением его высоты, ширины и глубины. Вы можете принять входные данные как строку с разделителями новой строки или массив строк.
Длина каждого ребра - это расстояние между +
символами на его двух концах. Например, горизонтальный край +--+
имеет длину 3, а вертикальный край
+
|
|
|
+
имеет длину 4. Минимальная длина ребра равна 1. Приведенный выше пример кубоида имеет объем 2 * 3 * 4 = 24.
Правила и оценки
Вы можете написать полную программу или функцию, и побеждает меньшее количество байтов.
Контрольные примеры
.++..
+++++
+++++
.++..
1
...++....
...||....
...||....
+--++--++
+--++--++
...||....
...||....
...++....
3
..+-+....
..|#|....
+-+-+-+-+
|#|#|#|#|
|#|#|#|#|
+-+-+-+-+
..|#|....
..+-+....
12
.+---+.....
++---++---+
||###||###|
||###||###|
||###||###|
++---++---+
.+---+.....
16
....++.....
....||.....
....||.....
....||.....
+---++---++
|###||###||
|###||###||
|###||###||
+---++---++
....||.....
....||.....
....||.....
....++.....
16
...+--+......
...|##|......
...|##|......
+--+--+--+--+
|##|##|##|##|
+--+--+--+--+
...|##|......
...|##|......
...+--+......
18
....+--+.......
....|##|.......
....|##|.......
....|##|.......
+---+--+---+--+
|###|##|###|##|
+---+--+---+--+
....|##|.......
....|##|.......
....|##|.......
....+--+.......
24
....+-----+..........
....|#####|..........
....|#####|..........
....|#####|..........
+---+-----+---+-----+
|###|#####|###|#####|
|###|#####|###|#####|
|###|#####|###|#####|
|###|#####|###|#####|
+---+-----+---+-----+
....|#####|..........
....|#####|..........
....|#####|..........
....+-----+..........
120
Ответы:
Сетчатка ,
2928 байтПопробуйте онлайн!
Есть много способов приблизиться к этому в Retina, в зависимости от того, какую область вы хотите умножить, с какой стороны, поэтому я не уверен, насколько это оптимально, но на самом деле это уже намного короче, чем я думал.
В настоящее время у меня есть два других решения с тем же количеством байтов, которые кажутся более подходящими для игры, чем описанный выше подход:
Хотя в них я мог бы сохранить каждый байт, если предположил, что ввод заканчивается завершающим переводом строки, но я бы предпочел не полагаться на это.
И еще один, все еще в 28 байтах (этот фактически умножает три стороны вместо умножения одной области на сторону):
объяснение
Основная идея состоит в том, чтобы умножить площадь грани сверху на длину вертикальной стороны, которая касается границы длины ввода.
Я буду использовать следующий ввод в качестве примера (он имеет длину сторон 2, 3 и 4, поэтому область 24):
Стадия 1: Транслитерация
Регулярное выражение
\G\..+¶
соответствует строке, которая начинается с.
и непосредственно примыкает к предыдущей строке. Так что это соответствует всем строкам, которые содержат верхнюю грань. Сама сцена превращается.
вx
всех остальных персонажей (любых|+-#
)y
. Это дает нам следующий результат:Это имеет еще один столбец,
y
чем нам нужно представить площадь верхней грани. Мы исправим это на следующем этапе.Этап 2: заменить
Таким образом, мы сопоставляем a
y
, которому предшествует anx
(который является точно одним из них на строку), и удаляем их обоих из строки. Мы получаем это:Итак, теперь у нас есть область верхней грани, представленная числом
y
s.Этап 3: заменить
Наша цель здесь состоит в том, чтобы умножить эту область
A
на длину отсутствующей стороны, которая является числом|
в начале строки плюс 1. Однако на самом деле проще умножить на число,n+1
потому что у нас уже есть одна копияA
строки , Если мы заменимn
вещи наA
, мы получимn+1
копииA
. Это делает все намного проще для нас.Таким образом, мы просто заменяем любые
|
сразу после перевода строки всем, что находится перед матчем. Это существенно искажает строку и делает ее немного больше, чем нам нужно, но числоy
s в конечном итоге является результатом, который мы ищем:Этап 4: Матч
Осталось только посчитать число
y
s, которое выводится в виде десятичного числа в конце.источник
Python 2, 57 байт
Функция, которая принимает список строк.
Определяет 3 измерения отдельно:
l[0].find('+')
Индекс первого
+
в первом ряду.-~l[0].count('-')
Количество
-
знаков в первом ряду.~`l`.count("'|")
Количество строк, начинающихся с
|
символа, через строковое представление списка с символом кавычки перед ним.62 байта:
Функция, которая принимает список строк и печатает результат.
Находит одно измерение
a
как индекс+
в первой строке. Из него выводятся два других измерения, а также ширина и высота входного прямоугольника.Альтернатива 63 байта, нахождение размеров отдельно:
источник
Bash + coreutils,
8377 байтправок:
Golfed
Разъяснения
Преобразуйте с помощью sed :
Избавьтесь от перевода строки с помощью обратных кавычек, добавьте)
Передать полученное выражение в bc
Тест
Попробуйте онлайн! (вместо bc используется расширение арифметики bash, поскольку последнее недоступно)
источник
Улитки , 19 байт
Попробуйте онлайн.
Идея состоит в том, что мы начинаем где-то с самого правого края в сети, а затем отправляемся куда-нибудь в самый нижний край. Длина ребра и площадь грани умножаются на механизм подсчета всех подходящих путей.
источник
JavaScript (ES6), 67
91Тест
источник
Руби, 44
Работает по принципу, аналогичному другим ответам: найдите первый,
+
чтобы найти глубину, найдите следующий.
после,+
чтобы найти ширину, и посчитайте число|
в конце строки и добавьте 1, чтобы найти высоту.разряженный в тестовой программе
источник
05AB1E , 21 байт
Позвольте
W
иH
быть соответственно ширина и высота ввода - не поле. Тогда размеры коробкиA
,B
иC
соблюдать следующие правила:На следующем рисунке показано , что
A
,B
иC
являются, с точки зрения краевых имен:Отсюда и вышеприведенные формулы. Эта программа вычисляет
A
, выводит значенияB
иC
и , наконец , вычисляет их продукт.Попробуйте онлайн!
Бывшая версия - Другой подход - 26 байт
источник
Befunge 93 , 56 байт
Попробуйте онлайн!
Объяснение:
Объем поля можно рассчитать путем умножения числа
.
s в первой строке перед любыми другими символами, числа+
и-
s в первой строке - 1, а также количества строк, начинающихся с|
+ 1.Мне пришлось перемещать IP вверх, а не вниз, чтобы использовать вертикаль, если в 3-й строке. Если IP шел вниз по линии, вертикальная if заставила бы вершину стека быть равной 1 при попадании в следующую горизонтальную if, отправляя его в неправильном направлении.
источник
Haskell,
6456 байтПопробуйте онлайн!
объяснение
Предполагается, что входными данными будет список строк для каждой строки, поэтому в
f
параметреx
находится первая строка иr
список оставшихся строк.fst(span(>'+')x)
возвращает.
-prefix первой строки в виде строки,length(fst(span(>'+')x))
как и первое измерениеd1
.['-' | '-' <- x]
возвращает строку со всеми-
в первой строке, поэтому возвращает1 + length['-' | '-' <- x]
второе измерениеd2
.|
можно сосчитать число в первом ряду,1 + length['|' | '|':_ <- r]
как и в третьем измеренииd3
.Понимание списка из 2. и 3. может быть сокращено до
1+sum[1|'-'<-x]
и1+sum[1|'|':_<-r]
путем составления списка из них для каждого вхождения '-' или '|' а затем взять сумму. Далее мы можем поставить внешнее1+
в списке понимание, добавляя-
кx
и"|"
кr
с получениемsum[1|'-'<-'-':x]
иsum[1|'|':_<-"|":r]
. Теперь мы можем объединить оба понимания списков, поместив оба предиката в одно и то же понимание: дляsum[1|'|':_<-"|":r,'-'<-'-':x]
удобства это точно вычисляет произведение двух измерений, потому что для списковF
иG
следующего понимания списков является декартовым произведениемF x G =[(a,b)|a<-F,b<-G]
.Наконец, вместо умножения 1. на комбинацию 2. и 3. мы можем использовать
>>
оператор в списках:F>>G
повторяетG
length F
время и объединяет результат. Такfst(span(>'+')x)>>[1|'|':_<-"|":r,'-'<-'-':x]
повторяет списокd2*d3
Onesd1
раз, получая списокd1*d2*d3
тех , которые затем суммируются , чтобы получить объем.источник
lines
.Java 8,
185129 байтспасибо Згарбу за -56 байт
golfed:
ungolfed:
объяснение
a*b*h = ((length_of_line-2*h-1)/2)*(number_of_lines-2*h-1)*h
где
a
иb
размеры базы иh
высота. Вы можете найтиh
, посчитав первыеh
строки, где вы начинаете с.
.источник
Java, 112 байт
Expanded:
источник
Powershell,
6867 байтЗаметка:
"$args"|% i*f +
это ярлык для"$args".indexOf('+')
объяснение
Хорошее объяснение взято из взято из ответа Osable :
Позвольте
W
иH
быть соответственно ширина и высота ввода - не поле. Тогда размеры коробкиA
,B
иC
соблюдать следующие правила:На следующем рисунке показано , что
A
,B
иC
являются, с точки зрения краевых имен:И
C
это позиция первого+
в первой строке ввода.Тестовый скрипт:
Выход:
источник
Wolfram Language (Mathematica) , 64 байта
Попробуйте онлайн!
Использует число
.
,|
и\n
символы во входных данных , чтобы решить для объема. Это выглядит глупо, потому что вместо него есть новая строка\n
.Если
A
,B
иC
являются сторонами, то. = 2C(A+2C)
,| = 5B+4C-9
и\n = B+2C
, так что мы можем решить для объемаABC
с точки зрения этих трех символов.источник