Marching Squares é um algoritmo de computação gráfica, usado para recuperar isocontours 2D a partir de uma grade de amostras (veja também, seu irmão mais velho, Marching Cubes, para configurações 3D). A idéia é processar cada célula da grade de forma independente e determinar os contornos que passam por essa célula com base nos valores em seus cantos.
A primeira etapa deste processo é determinar quais arestas são conectadas por contornos, com base em se os cantos estão acima ou abaixo do valor do contorno. Por uma questão de simplicidade, consideraremos apenas os contornos ao longo do valor 0
, para que tenhamos interesse se os cantos são positivos ou negativos. Existem casos para distinguir:24 = 16
Fonte da imagem: Wikipedia
A identificação de branco e preto realmente não importa aqui, mas, por definição, diga que branco é positivo e preto é negativo. Iremos ignorar casos em que um dos cantos é exatamente 0
.
Os pontos de sela (casos 5 e 10) oferecem um pouco de dificuldade extra: não está claro quais diagonais devem ser usadas apenas olhando os cantos. Isso pode ser resolvido encontrando a média dos quatro cantos (ou seja, uma aproximação do valor central) e escolhendo as diagonais de modo que os contornos separem o centro dos cantos com o sinal oposto. Se a média for exata 0
, qualquer um dos casos poderá ser escolhido.
Normalmente, esses 16 casos são simplesmente armazenados em uma tabela de pesquisa. Isso é ótimo para eficiência, mas é claro que preferimos que o código seja curto por aqui. Portanto, sua tarefa é executar esta etapa de pesquisa e imprimir uma representação ASCII do caso no menor código possível.
O desafio
Você recebe os valores dos quatro cantos (números inteiros diferentes de zero) em uma ordem fixa de sua escolha. Você deve então gerar o layout correto dos contornos, resolvendo corretamente os casos dos pontos de sela.
Você pode escrever um programa ou função, recebendo entrada via STDIN (ou alternativa mais próxima), argumento da linha de comando ou argumento da função e exibindo o resultado via STDOUT (ou alternativa mais próxima), valor de retorno da função ou parâmetro da função (saída).
A entrada pode ser obtida em qualquer formato conveniente de sequência ou lista.
Os 16 casos serão representados na arte ASCII usando um dos seguintes blocos 5x5:
o---o o---o o---o
| | | | | | |
| | |---| | | |
| | | | | | |
o---o o---o o---o
o---o o---o o---o o---o
|/ | | \| | | | |
| | | | | | | |
| | | | |\ | | /|
o---o o---o o---o o---o
o---o o---o
|/ | | \|
| | | |
| /| |\ |
o---o o---o
Você não deve imprimir nenhum espaço em branco à esquerda ou à direita, mas pode imprimir uma única nova linha opcional.
Isso é código de golfe, então a resposta mais curta (em bytes) vence.
Casos de teste
Os casos de teste assumem que a entrada é fornecida em ordem superior esquerda , superior direita , inferior esquerda , inferior direita . Os casos de teste são apresentados em 9 grupos, um correspondente a cada uma das 9 representações dadas acima (na mesma ordem, começando na célula vazia, terminando com os dois pontos de sela).
[1, 2, 1, 3]
[-9, -2, -2, -7]
[4, 5, -1, -2]
[-1, -2, 3, 4]
[7, -7, 7, -7]
[-5, 5, -5, 5]
[1, -6, -4, -1]
[-2, 3, 3, 4]
[-1, 6, -4, -1]
[2, -3, 3, 4]
[-1, -6, 4, -1]
[2, 3, -3, 4]
[-1, -6, -4, 1]
[2, 3, 3, -4]
[3, -8, -9, 2]
[-3, 8, 9, -2]
[8, -3, -2, 9]
[-8, 3, 2, -9]
Além disso, os seguintes casos de teste podem retornar um dos pontos de sela (sua escolha):
[1, -4, -2, 5]
[-1, 4, 2, -5]