Dados 5 pontos distintos em um plano bidimensional, determine o tipo de seção cônica formada pelos pontos. A saída deve ser um dos circle
, hyperbola
, ellipse
, ou parabola
.
Regras
- Os pontos estarão na posição linear geral, significando que não há três pontos colineares e, portanto, a passagem cônica através deles será única.
- As coordenadas dos 5 pontos serão números decimais entre -10 e 10, inclusive.
- A precisão dos valores decimais / flutuantes deve ser a precisão do tipo flutuante / decimal nativo do seu idioma. Se o seu idioma / tipo de dados for de precisão arbitrária, você poderá usar 12 dígitos após o ponto decimal como a precisão máxima exigida, arredondando para zero (por exemplo
1.0000000000005 == 1.000000000000
). - A capitalização do produto não importa.
ellipse
Não é permitido emitir quando a seção cônica é realmente um círculo. Todos os círculos são elipses, mas você deve gerar o mais específico.
Em imprecisões e precisão de ponto flutuante:
Estou tentando simplificar o máximo possível, para que problemas com imprecisões de ponto flutuante não atrapalhem. O objetivo é que, se o tipo de dados fosse "valor mágico de precisão infinita" em vez de float / double, tudo funcionaria perfeitamente. Porém, como o "valor mágico de precisão infinita" não existe, você escreve um código que assume que seus valores são de precisão infinita e quaisquer problemas que surjam como resultado de imprecisões de ponto flutuante são recursos, não bugs.
Casos de teste
(0, 0), (1, 5), (2, 3), (4, 8), (9, 2) => hyperbola
(1.2, 5.3), (4.1, 5.6), (9.1, 2.5), (0, 1), (4.2, 0) => ellipse
(5, 0), (4, 3), (3, 4), (0, 5), (0, -5) => circle
(1, 0), (0, 1), (2, 1), (3, 4), (4, 9) => parabola
circle
parecem exigir a verificação da igualdade do flutuador para diferenciar de uma elipse muito redonda. Que precisão devemos assumir aqui?Respostas:
Matlab, 154 bytes
Economizei alguns bytes graças às sugestões de Suever.
Toma entrada como
[x1 y1;x2 y2;x3 y3; etc]
. Isso usou uma matriz de Vandermonde e encontra a base de seu espaço nulo, que sempre será um único vetor. Em seguida, calcula o discriminante e o usa para criar um índice entre 1 e 4, que é usado para obter a sequência.Ungolfed:
A
sign(...)
parte calcula o discriminante, dando 1 se for positivo (hipérbole), -1 se for negativo (elipse) e 0 se for 0 (parábola). Omax(...)
subtrai 1 se for um círculo. As matrizes do Matlab são de um índice, portanto, adicione 3 para fornecer os valores 1, 2, 3, 4 e use-o para indexar a matriz de nomes de seções cônicas.fonte
max() == 0
você pode simplificar:~max()
ones(length(p),1)
você poderia fazer1+p(:,1)*0
max()
coisa era bobagem da minha parte, eu tinha comparações lá antes e fiquei com preguiça, obviamente! Essa maneira de obter oones
é muito bom também.JavaScript (ES6), 316
323 347Qualquer linguagem mais adequada para lidar com matriz e determinante deve ter uma pontuação melhor (APL, J, CJAM, Jelly)
Referências: Forma geral de uma cônica , Cinco pontos determinam uma cônica , Sistema de equações lineares , Determinante
No plano cartesiano, a equação geral de uma cônica é
ter A ou B ou C não igual a 0 (caso contrário, é uma linha reta)
A ... F são seis incógnitas a serem encontradas. Com cinco pares de (x, y), podemos construir um sistema linear com cinco equações e o dimensionamento remove uma dimensão. Ou seja, podemos definir um de A, B ou C como 1 se não for 0 (e sabemos que pelo menos um não é 0).
Eu construo e tento resolver 3 sistemas: primeiro tentando A = 1. Se não for solucionável, então B = 1, então C. (Poderia haver uma maneira melhor, mas esse é o meu melhor na época)
Tendo os valores de A, B, C, podemos classificar a cônica olhando para o discriminante
d=B*B-4*A*C
Menos golfe
Teste
fonte
Python - 234 bytes
Eu nunca imprimir
circle
ouparabola
porquet
ed[1]
nunca bateu exatamente0
, mas OP disse que estava bem.fonte
C, 500
Minha resposta JavaScript foi portada para C. Apenas para ver se isso pode ser feito.
Uso: leia 10 valores da entrada padrão
Resultado:
Teste (ideona)
Menos golfe
fonte
Sábio, 247 bytes
Experimente online
Esta função tem uma iteráveis de
(x,y)
pares como entrada, tenta calcular o discriminante de cada um dos sistemas lineares possíveis 3 (A=1
,B=1
, eC=1
), e emite o tipo de secção cónica com base nos valores da discriminante,A
,B
, eC
.Provavelmente há mais golfe a ser feito, mas estou enferrujada com Sage e estou com sono agora, então vou trabalhar mais de manhã.
fonte