Considere a possibilidade de representar uma curva bidimensional simples , aberta , em uma grade de texto com largura W de largura por H, onde X
representa parte da curva e .
representa o espaço vazio e nenhum outro caractere é usado.
Todo espaço de grade possui 8 espaços de grade vizinhos, seu bairro Moore . Espaços de grade além das bordas são considerados vazios.
Uma grade contém uma curva se tiver exatamente um X
OU se tiver mais de um em X
que:
- Exatamente dois
X
s têm apenas um vizinhoX
. Estes são os pontos finais da curva. - Cada
X
além dos endpoints vizinhos exatamente doisX
s. Estes formam a maior parte da curva.
Por exemplo, esta grade em que W = 9 e H = 4 contém uma curva:
....X.... .X.X.X.X. X..X..X.X .XX.....X
Da mesma forma, essas grades (W = 4, H = 3) têm curvas:
.... .X.. .... .... .X.X .... X..X ..X. XX.. X.X. ..X. .XX. .X.. .... ....
Essas grades, no entanto, não contêm uma curva:
.... .XX. ...X XX.. .... X.X. .... X..X ..XX XX.. .X.X .X.. .... .XX. .X.. .... ...X X.X.
Podemos encontrar o comprimento de uma curva somando as distâncias entre todos os pares vizinhos de X
s:
A distância entre dois
X
s ortogonais vizinhos é de 1 unidade.XX
X X
A distância entre dois
X
s diagonalmente vizinhos é √2 unidades.X. .X
.X X.
Por exemplo, o comprimento da curva na grade
XXX. ...X ..X.
pode ser visualizado como
então podemos ver que é 1 + 1 + √2 + √2 = 4.828427 ...
O comprimento de uma curva com apenas uma X
é zero.
Quando uma grade não forma uma curva, seu comprimento não está bem definido.
Desafio
Dada uma grade de texto de X
s e .
s, imprima o comprimento da curva que ela contém, ou imprima algo como -1
ou Null
para indicar que a grade não tem curva.
Para entrada, você pode usar outros caracteres além de X
e .
se desejar, e H e W podem ser considerados como entrada, se necessário. A entrada como uma lista ou matriz aninhada preenchida com 1s e 0s em vez de uma sequência também é boa.
Você pode emitir uma flutuação para o comprimento da curva ou, alternativamente, dois números inteiros A e B, onde length = A + B*√2
.
O código mais curto em bytes vence.
Casos de teste
XXX.
...X
..X.
2 + 2*√2 = 4.828427...
....X....
.X.X.X.X.
X..X..X.X
.XX.....X
3 + 8*√2 = 14.313708...
....
....
..X.
0 + 0*√2 = 0
.X..
X..X
.XX.
1 + 3*√2 = 5.242640...
....
..X.
.X..
0 + 1*√2 = 1.414213...
....
XX..
....
1 + 0*√2 = 1
.X.X
X.X.
....
0 + 3*√2 = 4.242640...
....
....
....
....
-1
.XX.
X..X
.XX.
-1
...X
..XX
.X..
-1
....
.X.X
...X
-1
X.X.
.X..
X.X.
-1
fonte
[x.x,...,.x.]
não é uma curva válida, certo?Respostas:
MATL ,
5251 bytesEntrada é uma matriz de zeros e uns.
Saída é
B
, entãoA
. As não curvas dão um negativoA
.Experimente online! Ou verifique todos os casos de teste .
Explicação
A computação do comprimento da curva usa duas convoluções 2D 1 : uma com a máscara de Moore e outra com uma máscara que contém apenas os vizinhos diagonais. Os resultados são duas matrizes com o mesmo tamanho da entrada, que serão indicadas como M e D, respectivamente. M fornece o número total de vizinhos para cada ponto, enquanto D fornece o número de vizinhos na diagonal.
Os resultados em M e D devem ser filtrados para descartar pontos que não pertencem à curva. Além disso, eles devem ser divididos por 2, porque "ser vizinho de" é uma relação simétrica, de modo que cada ponto da curva é contado duas vezes.
Determinar se a curva é válida é mais complicado do que eu esperava. Para fazer isso, o código testa três condições:
2
? (Ou seja, existem exatamente dois pontos com um único vizinho?)2
menos2
? (Juntamente com a condição 1, isso testa se todos os valores diferentes de zero em M, exceto dois deles iguais2
)A curva é válida se as condições 1 e 2 forem verdadeiras ou se a condição 3 for.
1 Convolução é a chave do sucesso .
fonte
Python 3 ,
316315311 bytesEu acho que isso cobre todos os casos; pelo menos os casos de teste funcionam.
Além disso, certamente ainda há muito para jogar golfe, provavelmente no começo, onde os casos extremos são tratados.
Experimente online!
Como funciona:
d,R,C
são 1. uma lista de listas com 1 como curva e 0 como plano de fundo, 2. contagem de linhas e colunasd
para que não tenhamos que nos preocupar com a borda da matriz 2DAgradecemos a @Helka Homba por apontar um caso ausente. Obrigado a @TuukkaX e @Trelzevir pelas dicas de golfe.
fonte
d=[[1,0,1],[0,1,0],[1,0,1]]
falhará aqui (adicionou caso de teste).s=sum
salva 4 bytes.Mathematica,
153150 bytesLeva uma matriz 2D, com
0
s para.
s e1
s porX
s. SaídasNull
para não curvas.O Mathematica possui 45 bytes incorporados para isso, mas gera alguns números para não curvas e 1 / sqrt (2) para entrada
{{1}}
. Corrigir esses custos 105 bytes (pode ser jogado no golfe?).fonte