Um labirinto é dado como uma matriz de 0s (paredes) e 1s (espaço acessível) em qualquer formato conveniente. Cada célula é considerada conectada aos seus 4 (ou menos) vizinhos ortogonais. Um componente conectado é um conjunto de células passáveis, todas conectadas transitivamente umas às outras. Sua tarefa é identificar os pontos de corte - células acessíveis que, se transformadas em paredes, alterariam o número de componentes conectados. Saída de uma matriz booleana com 1 s apenas nesses locais. O objetivo é fazê-lo com o menor número de bytes de código.
A matriz de entrada consistirá em pelo menos 3 linhas e 3 colunas. Pelo menos uma de suas células será uma parede e pelo menos uma poderá ser percorrida. Sua função ou programa deve poder processar qualquer um dos exemplos abaixo em menos de um minuto no TIO (ou no seu próprio computador, se o idioma não for suportado pelo TIO).
in:
11101001
11011101
00000001
11101111
11110101
00011111
10110001
11111111
out:
01000000
00001001
00000001
00000101
00110000
00010000
00000000
11100000
in:
1111111111111111
1000000000000001
1111111111111101
0000000000000101
1111111111110101
1000000000010101
1011111111010101
1010000001010101
1010111101010101
1010101111010101
1010100000010101
1010111111110101
1010000000000101
1011111111111101
1000000000000001
1111111111111111
out:
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
in:
1011010001111010
1111111011101101
1110010101001011
1111001110010010
1111010000101001
0111101001000101
0011100111110010
1001110011111110
0101000011100011
1110110101001110
0010100111000110
1000110111011010
0100101000100101
0001010101100011
1001010000111101
1000111011000010
out:
0000000000111010
1011110001001000
0000000000000011
0000000100010000
0000010000101000
0000001000000100
0000000011000000
1001100000011110
0000000001000010
0110100001000110
0000100101000010
1000100000000000
0100001000000100
0000000100100001
0000010000111000
0000010000000010
Respostas:
Stax , 40 bytes
Executar e depurar casos de teste
Este programa recebe entrada como uma sequência separada por espaços, contendo linhas. A saída está no mesmo formato. Aqui está a representação ascii descompactada.
A operação fundamental para contar uma ilha funciona assim.
'1'
por a'2'
.'12|21'
por'22'
.'1'
na string. O número de repetições é o número de ilhas..
Programa de 44 bytes de bônus - esta versão entra e sai usando o formato de grade.
fonte
MATL , 26 bytes
A entrada é uma matriz numérica, usando
;
como separador de linhas.Experimente online! Ou verifique todos os casos de teste .
Explicação
fonte
Perl 5 ,
-p0
10510196939089 bytesUsa em
b
vez de1
na entrada.Verifique se a matriz no STDIN é finalizada com uma nova linha
Experimente online!
Usa 3 níveis de substituição!
Esta versão de 87 bytes é mais fácil de interpretar nos formatos de entrada e saída, mas não está competindo, pois usa 3 caracteres diferentes na saída:
Experimente online!
É fácil salvar outro byte (o
s
modificador regex ) nas duas versões usando algum caractere diferente (não alfanumérico) como terminador de linha (em vez de nova linha), mas isso torna a entrada bastante ilegível novamente.Como funciona
Considere a substituição
Ele encontrará duas letras diferentes e próximas umas das outras na horizontal ou na vertical e as substituirá por
c
. Em um labirinto cujos caminhos consistem inteiramente na letra,b
nada acontecerá, pois as letras são as mesmas, mas assim que uma das letras for substituída por outra (por exemploz
), essa letra e um vizinho serão substituídos porc
uma aplicação repetida. inundação do componente conectado com ac
partir da sementez
.Neste caso, no entanto, não quero um preenchimento completo. Eu quero preencher apenas um dos braços vizinhos
z
, então, após o primeiro passo, queroz
ir embora. Isso já funciona com ac$2c
substituição, mas depois pretendo reiniciar um preenchimento de inundação ao longo de outro braço, começando do mesmo ponto e não sei mais qual delesc
era originalmentez
. Então, ao invés, eu usob | a
éc
,b | c
éc
ez | a
é{
. Assim, em um labirinto com caminhos compostosb
e uma sementez
no primeiro passob
será substituídac
ez
substituída pela{
que não é uma letra e não corresponde\w
e, portanto, não causará preenchimentos adicionais. Noc
entanto, isso manterá um novo preenchimento de inundação e um braço vizinho da semente será preenchido. Por exemplo, começando dePosso, então, substituir todos os c por alguns carta não (por exemplo
-
) e substitua{
porz
outra vez para reiniciar a inundação-fill:e repita esse processo até que todos os vizinhos da semente tenham sido convertidos. Se eu substituir novamente
{
porz
e preencher:Os
z
restos ficam para trás no final, porque não há vizinho com quem fazer uma transformação. Isso deixa claro o que acontece no seguinte fragmento de código:Encontre a primeira nova linha. O deslocamento inicial está agora em
@-
O regex discutido acima com
@{-}
o número de colunas (uma vez que plain@-
confunde o analisador perl e não o substitui adequadamente)O
/\n/
sempre é bem-sucedido e a substituição é verdadeira desde que ainda possamos inundar. Portanto, a parte seguinte&&
é executada se o preenchimento de um braço for concluído. Caso contrário, o lado esquerdo é avaliado como uma sequência vaziaReinicie o preenchimento e retorne 1 se o preenchimento anterior tiver feito alguma coisa. Caso contrário, retorne a string vazia. Todo esse código está envolvido
Portanto, se isso for executado em uma string inicial
$_
com az
na posição inicial, o código dentro será executado muitas vezes retornando nada, mas1
sempre que um braço vizinho for inundado. Efetivamente$_
é destruído e substituído por tantos1
s quantos componentes conectados estiverem conectadosz
. Observe que o loop precisa ser executado até a soma dos tamanhos dos componentes + número de vezes de armas, mas isso é bom, pois ele "número de caracteres, incluindo novas linhas * 2 + 1" vezes.O labirinto é desconectado se não houver
1
(corda vazia, um vértice isolado) ou se houver mais de 1 braço (mais de 21
s). Isso pode ser verificado usando o regex/\B/
(isso fornece, em0
vez de1
versões perl mais antigas. É discutível qual deles está errado). Infelizmente, se não corresponder, isso dará uma string vazia em vez de0
. No entanto, os:|.: code :seg
foi projetado para sempre retornar um número ímpar, fazendo um&
com/\B/
isso dará0
ou1
.Tudo o que resta é caminhar por toda a matriz de entrada e, em cada posição caminhável, semear
z
e contar os braços conectados. Isso é feito facilmente com:O único problema é que nas posições não passíveis de passagem o valor antigo é mantido. Como precisamos de
0
s lá, isso significa que a matriz de entrada original deve ter0
nas posições não passíveis de passagem e0
correspondências\w
na substituição original e provocaria enchentes. É por isso que eu uso\pL
(apenas as letras correspondentes).fonte
Java 8,
503489459455 bytes-18 bytes graças a @ceilingcat .
Explicação:
Experimente online.
fonte
Python 2 , 290 bytes
Experimente online!
-11 bytes graças a Rod
-11 bytes graças a Lynn
fonte
F(m,i,j)
em cada elemento, economizando 11 bytesfor q in((i,j+1),(i,j-1),(i+1,j),(i-1,j)):
->for q in(i,j+1),(i,j-1),(i+1,j),(i-1,j):
- rm outer parensF
retorna implicitamenteNone
, você pode usar emF(m,i,j)or c
vez de[F(m,i,j)]and c
.and m[i][j]
pode ser>0<m[i][j]
e[q[:]for q in m]
pode sereval(`m`)
.Wolfram Language (Mathematica) , 118 bytes
Experimente online!
fonte
Javascript 122 bytes
Entrada / saída como uma sequência multilinha.
Para cada célula passável, coloque um bloco e tente preencher as 4 células vizinhas. Se a célula atual não for um ponto de corte, a partir de qualquer vizinho aberto preencherá todos eles. Senão, precisarei de mais de uma operação de preenchimento para alcançar todas as células vizinhas.
Menos golfe
Teste
fonte