Вызов
По графическому вводу фигуры определите, сколько в ней отверстий.
Не дублировать
Этот вопрос был отмечен как возможный дубликат Графских островов . Я считаю, что эта задача отличается от задачи на Острове Графов, потому что в этой вы должны выяснить, как устранить блоки, которые касаются границы.
вход
Входные данные будут представлены в виде двухмерной формы ввода: многострочная строка, массив строк или массив символьных массивов. Это представляет форму. Форма гарантированно будет только в одной части, соединенной ребром. Пожалуйста, укажите, как вы хотите, чтобы ввод был принят.
Выход
Выход - одно целое число, указывающее, сколько отверстий в форме. Разрешающий символ новой строки разрешен, но нет других начальных или конечных пробелов. Другими словами, выходные данные должны соответствовать регулярному выражению ^\d+\n?$
.
Что такое дыра?
Это одиночные отверстия:
####
# #
# #
####
####
# #
# ##
###
#####
# # #
# #
#####
Это не дыры:
########
########
# ####
# ####
# ######
#
########
###
#
###
##########
#
# ########
# # #
# # #### #
# # ## #
# ###### #
# #
##########
В значительной степени, если этот промежуток соединяется с внешним краем, это не дыра.
Контрольные примеры
#####
# # # -> 2
#####
#####
#
# ### -> 1
# # #
#####
####
## # -> 1 (things are connected by edges)
# ##
####
###
### -> 0 (You must handle shapes with no holes, but input will always contain at least one filled space)
###
Вы можете использовать любой символ вместо «#» и вместо пробелов.
Критерии объективной оценки
Оценка дается как количество байтов в вашей программе.
выигрыш
Победитель будет представлен с самым низким счетом, к 4 апреля.
###|# #|##
в качестве теста? Это должно быть0
, верно?Ответы:
MATLAB / Octave, 18 байт
Попробуйте онлайн!
Это анонимная функция, принимающая логическую матрицу в качестве входных данных. Объект формируется из
true
записей (с указанным подключением), пустое пространство - этоfalse
записи.bweuler
затем вычисляет число Эйлера двоичного изображения, представленного этой матрицей, то есть количество объектов минус число отверстий.источник
Mathematica,
5957 байтДля этого есть встроенная функция. Вводит в виде 2D матрицы
1
s (стены) и0
s (отверстия). Для удобства вот все тестовые примеры в этом формате ввода:Альтернативное решение, 59 байт
Это был мой оригинальный подход. Он также основан на встроенных компонентах, но не учитывает отверстия напрямую (вместо этого он рассматривает сами отверстия как компоненты).
Принимает тот же формат ввода, что и выше, но с ролями
0
s и1
s поменялись местами.Причина, по которой мне нужно преобразовать это в
Image
первое, заключается в том, что в противном случае Mathematica рассмотрела бы все1
-элементы как часть одного компонента (потому что обрабатывает матрицу как матрицу меток компонента). Следовательно, если какой-либо1
элемент граничит с полем, он удалит их все. КогдаDeleteBorderComponents
вместо этого используется образ, он выполняет неявную проверку подключения, чтобы найти компоненты.В качестве альтернативы я мог бы вызвать
MorphologicalComponents
первым , что превратило бы ввод в подходящую матрицу меток, но если я сделаюDeleteBorderComponents
второе, то больше не гарантируется, что максимальная метка компонента соответствует количеству компонентов (потому что я мог бы удалить меньший компонент).источник
GenerateBuiltin
. Он генерирует встроенный для любого вызова, который не имеет встроенного. Кроме того, мне плохо из-за входящих сообщений Мартина Эндера, поэтому, если хотите, давайте продолжим эту дискуссию здесьPerl 5 , 154 байта
152 байта кода + 2 байта для
-p0
флага.Попробуйте онлайн!
Я думаю, что код довольно понятен.
Если вам нужны некоторые объяснения, чтобы понять, вот несколько шагов преобразований, сделанных программой на простой ввод (исходя из отсюда ), а затем некоторые пояснения ниже:
Сначала
s/^ | $/A/gm;s/^.*\K | (?=.*$)/A/&&redo
заменим пробелы на границе (1-е регулярное выражение для левого / правого, 2-е для нижнего / верхнего) наA
(я выбираю этот символ совершенно произвольно).Затем мы получаем ширину формы с
/.*/;$@="@+"-1;
.Теперь мы хотим заменить каждое пространство, которое связано с a,
A
наA
(потому что, если пространство связано с aA
, это означает, что оно не может быть частью дыры. Это сделаноfor$%(A,X){(s/$%(.?.?.{$@})? /$%$1$%/s||s/ (.?.?.{$@})?$%/$%$1$%/s)&&redo}
. (Вы заметите, что это сделано один раз дляA
s и один дляX
s - объяснения дляX
ниже приведены.) Здесь есть два регулярных выражения:s/$%(.?.?.{$@})? /$%$1$%/s
имеет дело с пробелами, которые находятся справа или снизу от А.A
Иs/ (.?.?.{$@})?$%/$%$1$%/s
с пробелами сверху или слева отA
.На данный момент единственные пробелы, которые остаются в строке, являются частью отверстий.
Пока еще есть пробелы, мы повторяем:
- Чтобы узнать, сколько там дырок, мы заменяем пробел на
X
(s/ /X/
) и увеличиваем счетчик дырок ($\++
), и переделываем всю программу (на самом деле, мы хотим только повторитьfor
цикл , но это меньше байтов, чтобы переделать всю программу).- Затем
for
цикл заменит все пробелы, которые связаны с, наX
aX
, так как они являются частью одного и того же отверстия.В конце,
$\|=0
гарантирует, что если нет отверстий,0
вместо пустой строки печатается a. И$\
неявно печатается благодаря-p
флажку.источник
Python 2, 282 байта
+100 для обработки диагональных касаний TT_TT (нам это действительно нужно?)
-119 благодаря руководству @Rod :)
Попробуйте онлайн . Принимает массив массивов символов «#» и пробелов в качестве входных данных.
Ищет первый пробел и помечает его как непустое ('#'). Рекурсивно проверяйте все окружающее, заполняя все пустые ячейки. Если какая-либо пустая ячейка текущей «дыры» окажется на счетчике границы, она не изменится, в противном случае она будет увеличена на 1. Повторяйте процесс до тех пор, пока не останется больше пробелов.
источник
sum(A,[])
чтобы сгладитьNone
с, но это не имеет значения)x=T[0];y=T[1]
->x,y=T
, вы (возможно) не нужно объявлятьg=1
на 3 - й линии, и вы можете использовать<
или>
для сравнения строк (он будет приниматьord()
значение каждого полукокса) позволяет заменитьA[y][x]!='#'
сA[y][x]<'#'
, так' '<'#'
.Python 2,
233225222 байтаmath_junkie : -8 байт
Принимает 2d массив логических / целых чисел (0/1) в качестве входных данных
Попробуйте онлайн!
Отформатированная версия:
источник
print sum(m(x,y)...
вместоa=
иprint a
C # 7, 364 байта
Менее чем доволен этим ... может быть, кто-то еще может разобраться с этим ... Если у меня будет энергия позже, я переверну первый цикл и посмотрю, может ли это помочь обрезать проверку границ.
Попробуйте онлайн
Завершить программу, принимает вход для стандартного входа, выход для стандартного выхода. Использует непересекающиеся наборы, чтобы определить временные дыры, и когда убивает любое прикосновение к границам (с некоторой хитростью для верхнего края).
Отформатированный и закомментированный код:
источник
Func<List<string>, int>
чтобы удалить пух и консольные вещи. Тем не менее, я видел, что у вас есть локальные функции, поэтому вы не сможете использовать их в функции. Можно просто скомпилировать в методint h(string[] s) { }
.Улитки , 48 байт
Ungolfed:
источник
JavaScript (ES6), 192 байта
Основываясь на моем ответе Обнаружить провальные замки» . Сначала строка дополняется пробелами, чтобы создать область вокруг фигуры. Затем RegExp ищет два соседних квадрата, один из которых содержит
@
, другой содержит пробел, и заменяет их оба на@
. Если он не может этого сделать, он заполняет пробел знаком@
и считается как новая дыра. Наконец один вычитается для учета окружающей области.источник