Nota: O título desta pergunta deve ser "Loop It", mas como o título precisa ter pelo menos 15 caracteres, existem alguns espaços invisíveis. Esta nota é tal que o desafio pode ser pesquisado.
Desafio
Dada uma lista finita de pontos integrais únicos no plano, encontre um polígono cujos vértices são exatamente aqueles pontos que não se intersectam.
Detalhes
- Como entrada, você pode fazer, por exemplo, duas listas com as coordenadas x e y ou uma lista de pares.
- A lista de entrada contém pelo menos 3 pontos.
- Observe que isso significa que nunca há uma solução única.
- Pode-se supor que a lista de entradas não seja co-linear (os pontos não podem estar contidos em uma linha), isso significa que realmente existe um polígono que não se intercepta.
- Os ângulos em cada vértice são arbitrários, incluindo 180 °.
- Para uma entrada de comprimento
n
, a saída deve ser uma permutação(p1,p2,p3,...,pn)
de(1,2,3,...,n)
onde ak
-ésima entradapk
representa op
-ésimo ponto na lista de entradas. Isso significa que temos uma linha dep1
parap2
, uma linha dep2
parap3
etc, bem como uma linha depn
parap1
. (Você também pode usar os índices baseados em 0). Como alternativa, você pode simplesmente exibir a lista de pontos de entrada na ordem correta.
Exemplos
Digamos que temos os pontos [(0,0),(0,1),(1,0),(-1,0),(0,-1)]
e queremos representar o seguinte caminho:
Isso significa que exibiríamos a lista [5,1,4,2,3]
Aqui estão mais algumas sugestões para tentar (recomendo examinar os gráficos correspondentes para verificar os objetivos).
Triangle
[(0,0),(0,1),(1,0)]
S-Curve
[(0,0),(0,1),(0,2),(0,3),(0,4),(1,0),(2,0),(2,1),(2,2),(2,3),(2,4),(3,4),(4,0),(4,1),(4,2),(4,3),(4,4)]
L-Shape
[(4,0),(1,0),(3,0),(0,0),(2,0),(0,1)]
Menger Sponge
[(1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1),(11,1),(12,1),(13,1),(14,1),(15,1),(16,1),(17,1),(18,1),(19,1),(20,1),(21,1),(22,1),(23,1),(24,1),(25,1),(26,1),(27,1),(1,2),(3,2),(4,2),(6,2),(7,2),(9,2),(10,2),(12,2),(13,2),(15,2),(16,2),(18,2),(19,2),(21,2),(22,2),(24,2),(25,2),(27,2),(1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3),(9,3),(10,3),(11,3),(12,3),(13,3),(14,3),(15,3),(16,3),(17,3),(18,3),(19,3),(20,3),(21,3),(22,3),(23,3),(24,3),(25,3),(26,3),(27,3),(1,4),(2,4),(3,4),(7,4),(8,4),(9,4),(10,4),(11,4),(12,4),(16,4),(17,4),(18,4),(19,4),(20,4),(21,4),(25,4),(26,4),(27,4),(1,5),(3,5),(7,5),(9,5),(10,5),(12,5),(16,5),(18,5),(19,5),(21,5),(25,5),(27,5),(1,6),(2,6),(3,6),(7,6),(8,6),(9,6),(10,6),(11,6),(12,6),(16,6),(17,6),(18,6),(19,6),(20,6),(21,6),(25,6),(26,6),(27,6),(1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7),(9,7),(10,7),(11,7),(12,7),(13,7),(14,7),(15,7),(16,7),(17,7),(18,7),(19,7),(20,7),(21,7),(22,7),(23,7),(24,7),(25,7),(26,7),(27,7),(1,8),(3,8),(4,8),(6,8),(7,8),(9,8),(10,8),(12,8),(13,8),(15,8),(16,8),(18,8),(19,8),(21,8),(22,8),(24,8),(25,8),(27,8),(1,9),(2,9),(3,9),(4,9),(5,9),(6,9),(7,9),(8,9),(9,9),(10,9),(11,9),(12,9),(13,9),(14,9),(15,9),(16,9),(17,9),(18,9),(19,9),(20,9),(21,9),(22,9),(23,9),(24,9),(25,9),(26,9),(27,9),(1,10),(2,10),(3,10),(4,10),(5,10),(6,10),(7,10),(8,10),(9,10),(19,10),(20,10),(21,10),(22,10),(23,10),(24,10),(25,10),(26,10),(27,10),(1,11),(3,11),(4,11),(6,11),(7,11),(9,11),(19,11),(21,11),(22,11),(24,11),(25,11),(27,11),(1,12),(2,12),(3,12),(4,12),(5,12),(6,12),(7,12),(8,12),(9,12),(19,12),(20,12),(21,12),(22,12),(23,12),(24,12),(25,12),(26,12),(27,12),(1,13),(2,13),(3,13),(7,13),(8,13),(9,13),(19,13),(20,13),(21,13),(25,13),(26,13),(27,13),(1,14),(3,14),(7,14),(9,14),(19,14),(21,14),(25,14),(27,14),(1,15),(2,15),(3,15),(7,15),(8,15),(9,15),(19,15),(20,15),(21,15),(25,15),(26,15),(27,15),(1,16),(2,16),(3,16),(4,16),(5,16),(6,16),(7,16),(8,16),(9,16),(19,16),(20,16),(21,16),(22,16),(23,16),(24,16),(25,16),(26,16),(27,16),(1,17),(3,17),(4,17),(6,17),(7,17),(9,17),(19,17),(21,17),(22,17),(24,17),(25,17),(27,17),(1,18),(2,18),(3,18),(4,18),(5,18),(6,18),(7,18),(8,18),(9,18),(19,18),(20,18),(21,18),(22,18),(23,18),(24,18),(25,18),(26,18),(27,18),(1,19),(2,19),(3,19),(4,19),(5,19),(6,19),(7,19),(8,19),(9,19),(10,19),(11,19),(12,19),(13,19),(14,19),(15,19),(16,19),(17,19),(18,19),(19,19),(20,19),(21,19),(22,19),(23,19),(24,19),(25,19),(26,19),(27,19),(1,20),(3,20),(4,20),(6,20),(7,20),(9,20),(10,20),(12,20),(13,20),(15,20),(16,20),(18,20),(19,20),(21,20),(22,20),(24,20),(25,20),(27,20),(1,21),(2,21),(3,21),(4,21),(5,21),(6,21),(7,21),(8,21),(9,21),(10,21),(11,21),(12,21),(13,21),(14,21),(15,21),(16,21),(17,21),(18,21),(19,21),(20,21),(21,21),(22,21),(23,21),(24,21),(25,21),(26,21),(27,21),(1,22),(2,22),(3,22),(7,22),(8,22),(9,22),(10,22),(11,22),(12,22),(16,22),(17,22),(18,22),(19,22),(20,22),(21,22),(25,22),(26,22),(27,22),(1,23),(3,23),(7,23),(9,23),(10,23),(12,23),(16,23),(18,23),(19,23),(21,23),(25,23),(27,23),(1,24),(2,24),(3,24),(7,24),(8,24),(9,24),(10,24),(11,24),(12,24),(16,24),(17,24),(18,24),(19,24),(20,24),(21,24),(25,24),(26,24),(27,24),(1,25),(2,25),(3,25),(4,25),(5,25),(6,25),(7,25),(8,25),(9,25),(10,25),(11,25),(12,25),(13,25),(14,25),(15,25),(16,25),(17,25),(18,25),(19,25),(20,25),(21,25),(22,25),(23,25),(24,25),(25,25),(26,25),(27,25),(1,26),(3,26),(4,26),(6,26),(7,26),(9,26),(10,26),(12,26),(13,26),(15,26),(16,26),(18,26),(19,26),(21,26),(22,26),(24,26),(25,26),(27,26),(1,27),(2,27),(3,27),(4,27),(5,27),(6,27),(7,27),(8,27),(9,27),(10,27),(11,27),(12,27),(13,27),(14,27),(15,27),(16,27),(17,27),(18,27),(19,27),(20,27),(21,27),(22,27),(23,27),(24,27),(25,27),(26,27),(27,27)]
Respostas:
Mathematica
2928 BytesFindShortestTour
(16 bytes) faz o truque, mas fornece algumas informações estranhas não solicitadas (o comprimento do caminho e um retorno ao ponto de partida).dá apenas a resposta (-1 byte graças a @ user202729)
Para visualizar, use
Graphics@Line[g[[%]]]
, onde%
está a permutação encontrada acima eg é a lista de pontos original.Aqui está a visualização da solução para a Menger Sponge:
Aqui está uma solução em 1000 pontos aleatórios:
A chave aqui é saber que a solução mais curta do problema do vendedor ambulante ou do viajante nunca produzirá cruzamentos quando a distância euclidiana for usada como métrica. Uma das etapas para localizar uma solução e garantir a otimização é remover essas interseções.
fonte
@*
parece salvar um byte.JavaScript (ES6),
365341 bytesSem nenhum built-in, isso acabou sendo muito mais longo do que eu esperava. Muitos bytes são gastos na detecção de segmentos colineares sobrepostos.
Recebe a entrada como uma matriz de
[x,y]
coordenadas. Retorna uma permutação da entrada.Demo
Esse trecho registra a saída e desenha o caminho correspondente em uma tela.
Mostrar snippet de código
Quão?
Aqui está a estrutura da principal função recursiva f () , deixando de lado o código de teste de interseção por enquanto:
Abaixo está o detalhe do teste de interseção () . Esta página fornece uma explicação abrangente sobre o algoritmo usado.
Finalmente, aqui está a definição da função auxiliar o () :
fonte
APL (Dyalog Classic) ,
4238 bytesExperimente online!
Entrada é uma lista de pares de coordenadas. A saída é uma permutação baseada em 0.
⍵
é a lista de pontos - o argumento para{ }
⍵[⊃⍋↑⍵]
é o ponto mais baixo mais à esquerda⍵-
converte todos os pontos para que o menor à esquerda fique na origem do sistema de coordenadas0j1
a unidade imaginária i = sqrt (-1)0j1⊥¨
decodifica as coordenadas como se dígitos em um sistema de números base-i - ou seja, transforma (x, y) em um número complexo ix + yz←
atribuir az
12○
calcula os argumentos dos números complexos, também conhecidos como ângulos teta ou função circular APL 12(⍪,(|z)ׯ1*⊢=⌈/)
é um trem que calcula uma máscara booleana de onde os ângulos estão no máximo (⊢=⌈/
), transforma o 0 1 na máscara em 1 ¯1, elevando ¯1 à potência correspondente (¯1*
), multiplicando pelas magnitudes dos números complexos|z
, e concatena isso à direita (,
) de uma matriz alta e fina de 1 coluna (⍪
) dos ângulos.⍋
grade - retorna a permutação que classificaria as linhas da matriz lexicograficamente em ordem crescentefonte