Quando você martela um conjunto de pregos em uma placa de madeira e enrola um elástico em volta deles, você obtém um Casco Convexo .
Sua missão, se você decidir aceitá-la, é encontrar o casco convexo de um determinado conjunto de pontos 2D.
Algumas regras:
- Escreva como uma função, as coordenadas da lista de pontos (em qualquer formato que você quiser) é o argumento
- A saída deve ser a lista de pontos no casco convexo listados no sentido horário ou anti-horário, começando em qualquer um deles.
- A lista de saída pode estar em qualquer formato razoável, onde as coordenadas de cada ponto são claramente distinguíveis. (Por exemplo, NÃO uma lista de uma dimensão {0.1, 1.3, 4, ...})
- Se três ou mais pontos em um segmento do casco convexo estiverem alinhados, apenas os dois extremos devem ser mantidos na saída
Dados de amostra:
Amostra 0
Entrada:
{{1, 1}, {2, 2}, {3, 3}, {1, 3}}
Saída:
{{3, 3}, {1, 3}, {1, 1}}
(As figuras são apenas ilustrativas)
Amostra 1
Entrada:
{{4.4, 14}, {6.7, 15.25}, {6.9, 12.8}, {2.1, 11.1}, {9.5, 14.9},
{13.2, 11.9}, {10.3, 12.3}, {6.8, 9.5}, {3.3, 7.7}, {0.6, 5.1}, {5.3, 2.4},
{8.45, 4.7}, {11.5, 9.6}, {13.8, 7.3}, {12.9, 3.1}, {11, 1.1}}
Saída:
{{13.8, 7.3}, {13.2, 11.9}, {9.5, 14.9}, {6.7, 15.25}, {4.4, 14},
{2.1, 11.1}, {0.6, 5.1}, {5.3, 2.4}, {11, 1.1}, {12.9, 3.1}}
Amostra 2
Entrada:
{{1, 0}, {1, 1}, {1, -1}, {0.68957, 0.283647}, {0.909487, 0.644276},
{0.0361877, 0.803816}, {0.583004, 0.91555}, {-0.748169, 0.210483},
{-0.553528, -0.967036}, {0.316709, -0.153861}, {-0.79267, 0.585945},
{-0.700164, -0.750994}, {0.452273, -0.604434}, {-0.79134, -0.249902},
{-0.594918, -0.397574}, {-0.547371, -0.434041}, {0.958132, -0.499614},
{0.039941, 0.0990732}, {-0.891471, -0.464943}, {0.513187, -0.457062},
{-0.930053, 0.60341}, {0.656995, 0.854205}}
Saída:
{{1, -1}, {1, 1}, {0.583004, 0.91555}, {0.0361877, 0.803816},
{-0.930053, 0.60341}, {-0.891471, -0.464943}, {-0.700164, -0.750994},
{-0.553528, -0.967036}}
Aplicam-se as regras padrão de código de golfe. Nenhuma biblioteca de geometria ad-hoc. Código mais curto vence.
Editar 1
Estamos procurando uma resposta algorítmica aqui, não uma rotina pré-programada com localizador convexo de cascos como esse no MatLab ou no Mathematica
Editar 2
Resposta a comentários e informações adicionais:
- Você pode assumir que a lista de entrada contém o número mínimo de pontos que melhor lhe convier. Mas você deve garantir o tratamento adequado de (sub) conjuntos alinhados.
- Você pode encontrar pontos repetidos na lista de entrada
- O número máximo de pontos deve ser limitado apenas pela memória disponível
- Re "ponto flutuante": você precisa ser capaz de processar listas de entrada com coordenadas decimais como as fornecidas nas amostras. Você pode fazer isso usando uma representação de ponto flutuante
.
Respostas:
Ruby, 168 caracteres
Esse código ruby também usa o algoritmo de embrulho para presente. A função
C
aceita uma matriz de pontos e retorna o casco convexo como matriz.Exemplo:
fonte
Mathematica 151
ainda trabalho em andamentoteste:
fonte
CoffeeScript, 276:
Se a função não precisar ser acessível, remova
f=
para cortar mais dois caracteres.Entrada / saída é uma única matriz de pontos, com cada ponto sendo definido pelas
x,y
propriedades. A matriz de entrada é modificada e retornada (se a última não for necessária, remova os dois últimos caracteres).A explicação pode ser adicionada mais tarde.
Conjunto de teste (não funcionará no oldIE):
ambiente de teste sugerido: http://coffeescript.org/
fonte
{{1, 1}, {2, 2}, {3, 3}, {1, 3}}
e retornou[{"x" : 1, "y" : 1, "r" : 0}, {"x" : 1, "y" : 3, "r" : 0}, "x" : 2, "y" : 2, "r" : 0.78..}]
enquanto eu acho que a resposta correta é alguma permutação de{{3, 3}, {1, 3}, {1, 1}}
Python,
209 205195Usa um algoritmo de embrulho de presente. O resultado começa com o ponto mais à esquerda e quebra no sentido anti-horário.
Exemplo:
h([(1, 1), (2, 2), (3, 3), (1, 3)])
retorna[(1, 3), (1, 1), (3, 3)]
fonte
print
para obter a saída?the output list can be in any reasonable format
era clara o suficiente. Você acha que precisa ser explicitamente declarado?h([(0, 1), (0,1), (0.1 , 1)])
me dá[(0, 1), (0.10000000000000001, 1)]