Desafio
Dada a entrada gráfica de uma forma, determine quantos furos existem nela.
Não duplicado
Esta questão foi marcada como uma possível duplicata das Ilhas Conde . Acredito que esse desafio seja diferente do desafio de Count Island porque, neste, você precisa descobrir como eliminar os blocos que tocam a fronteira.
Entrada
A entrada será fornecida como uma forma de entrada 2D, como uma cadeia de linhas múltiplas, uma matriz de cadeias ou uma matriz de matrizes de caracteres. Isso representa a forma. A forma é garantida em apenas uma peça, conectada pela borda. Especifique como deseja que a entrada seja recebida.
Resultado
A saída é um único inteiro informando quantos furos existem na forma. Uma nova linha à direita é permitida, mas nenhum outro espaço em branco à esquerda ou à direita. Em outras palavras, a saída deve corresponder à expressão regular ^\d+\n?$
.
O que é um buraco?
Estes são orifícios únicos:
####
# #
# #
####
####
# #
# ##
###
#####
# # #
# #
#####
Estes não são buracos:
########
########
# ####
# ####
# ######
#
########
###
#
###
##########
#
# ########
# # #
# # #### #
# # ## #
# ###### #
# #
##########
Praticamente, se a lacuna se unir à borda externa, não é um buraco.
Casos de teste
#####
# # # -> 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)
###
Você pode usar qualquer caractere no lugar do '#' e no lugar dos espaços.
Critérios de Pontuação Objetiva
A pontuação é dada como o número de bytes no seu programa.
Ganhando
O vencedor será a finalização com a menor pontuação, até o dia 4 de abril.
###|# #|##
como um caso de teste? Isso deveria ser0
, certo?Respostas:
MATLAB / oitava, 18 bytes
Experimente online!
Esta é uma função anônima que recebe uma matriz lógica como entrada. O objeto é formado pelas
true
entradas (com a conectividade especificada), o espaço vazio são asfalse
entradas.bweuler
depois calcula o número de euler da imagem binária representada por essa matriz, ou seja, o número de objetos menos o número de furos.fonte
Mathematica,
5957 bytesHá um built-in para isso. Recebe a entrada como uma matriz 2D de
1
s (paredes)0
es (furos). Por conveniência, aqui estão todos os casos de teste neste formato de entrada:Solução alternativa, 59 bytes
Esta foi a minha abordagem original. Também é baseado nos componentes relacionados ao componente, mas não conta os furos diretamente (em vez disso, trata os furos como componentes).
Tem o mesmo formato de entrada como acima, mas com os papéis de
0
s e1
s trocados.A razão pela qual eu preciso converter isso em um
Image
primeiro é que, caso contrário, o Mathematica consideraria todas as1
células como parte de um único componente (porque trata a matriz como uma matriz de rótulo de componente). Portanto, se alguma1
célula-delimitar a margem, ela excluirá todas elas. QuandoDeleteBorderComponents
é usado em uma imagem, ele faz uma verificação implícita de conectividade para encontrar os componentes.Como alternativa, eu poderia ligar
MorphologicalComponents
primeiro , o que transformaria a entrada em uma matriz de etiqueta adequada, mas, se o fizerDeleteBorderComponents
, não será mais garantido que o rótulo máximo do componente corresponda ao número de componentes (porque eu poderia excluir um componente menor).fonte
GenerateBuiltin
. Ele gera um built-in para qualquer desafio que não tenha um built-in. Além disso, eu me sinto mal por caixa de entrada do Martin Ender, então se você quiser, vamos continuar essa discussão aquiPerl 5 , 154 bytes
152 bytes de código + 2 bytes para
-p0
sinalizador.Experimente online!
Eu acho que o código é bastante auto-explicativo.
Se você precisar de algumas explicações para entender, aqui estão algumas etapas das transformações feitas pelo programa em uma entrada simples (vinda daqui ), seguidas de algumas explicações abaixo:
Primeiro,
s/^ | $/A/gm;s/^.*\K | (?=.*$)/A/&&redo
substituirá os espaços na borda (1º regex para esquerda / direita, 2º para inferior / superior) porA
(eu escolho esse caractere bastante arbitrário).Então, obtemos a largura da forma
/.*/;$@="@+"-1;
.Agora, queremos substituir todo espaço conectado a a
A
por aA
(porque se um espaço estiver conectado a aA
, significa que não pode fazer parte de um buraco. Isso é feito porfor$%(A,X){(s/$%(.?.?.{$@})? /$%$1$%/s||s/ (.?.?.{$@})?$%/$%$1$%/s)&&redo}
. (Você notará que isso é feito uma vez para seA
e um paraX
s - explicações para oX
abaixo) Existem dois regex aqui:s/$%(.?.?.{$@})? /$%$1$%/s
lida com os espaços que estão à direita ou na parte inferior de aA
. Es/ (.?.?.{$@})?$%/$%$1$%/s
com os espaços na parte superior ou esquerda de aA
.Nesse ponto, os únicos espaços restantes na cadeia de caracteres fazem parte dos furos.
Enquanto ainda existem espaços, repetimos:
- Para saber quantos buracos existem, substituímos um espaço por um
X
(s/ /X/
) e incrementamos o contador de buracos ($\++
) e refazemos o programa inteiro (na verdade, só queremos refazer ofor
loop , mas são menos bytes para refazer todo o programa).- Então, o
for
loop substituirá todo espaço conectado a aX
por aX
, pois eles fazem parte do mesmo furo.No final,
$\|=0
garante que, se não houver furos, a0
seja impresso em vez de uma sequência vazia. E$\
é implicitamente impresso graças à-p
bandeira.fonte
Python 2, 282 bytes
+100 para lidar com toques diagonais TT_TT (realmente precisamos disso?)
-119 graças às orientações @Rod :)
Experimente online . Toma matriz de matrizes de caracteres '#' e espaços em branco como entrada.
Procura o primeiro espaço em branco e o marca como não vazio ('#'). Verifique recursivamente tudo ao redor, enquanto preenche todas as células vazias. Se alguma célula vazia do "buraco" atual parecer estar no contador de borda não será alterada, caso contrário, ela será aumentada em 1. Repita o processo, até que não haja mais espaços em branco.
fonte
sum(A,[])
para achatarNone
s, mas isso é irrelevante)x=T[0];y=T[1]
->x,y=T
, você (provavelmente) não precisa declararg=1
na 3ª linha e pode usar<
ou>
comparar seqüências de caracteres (isso levará oord()
valor de cada caractere) permitindo que você substituaA[y][x]!='#'
porA[y][x]<'#'
, desde' '<'#'
.Python 2,
233225222 bytesmath_junkie : -8 bytes
Pega 2d matriz de booleanos / inteiros (0/1) como entrada
Experimente online!
Versão formatada:
fonte
print sum(m(x,y)...
em vez dea=
eprint a
C # 7, 364 bytes
Menos do que feliz com isso ... talvez alguém possa resolver isso ... Se eu tiver energia mais tarde, inverterei o primeiro loop e ver se isso pode ajudar a reduzir a verificação dos limites.
Experimente online
Programa completo, aceita entrada para entrada padrão, saída para saída padrão. Usa conjuntos disjuntos para determinar os furos provisórios e, quando mata qualquer um, toque nas bordas (com alguma desonestidade na borda superior).
Código formatado e comentado:
fonte
Func<List<string>, int>
para remover o material de cotão e console. No entanto, vi que você tem funções locais, portanto, talvez você não possa tê-las em uma função. Pode apenas compilar com um métodoint h(string[] s) { }
.Caracóis , 48 bytes
Ungolfed:
fonte
JavaScript (ES6), 192 bytes
Com base na minha resposta para Detectar falha de castelos . Primeiro, a corda é preenchida com espaços para criar uma área ao redor da forma. O RegExp procura então dois quadrados adjacentes, um contendo um
@
, um contendo um espaço e os substitui por um@
. Se não puder fazer isso, preenche um espaço com um@
e conta isso como um novo buraco. Finalmente, um é subtraído para dar conta da área circundante.fonte