Учитывая 5 различных точек на двумерной плоскости, определите тип конического сечения, образованного точками. Выход должен быть один из circle
, hyperbola
, ellipse
, или parabola
.
правила
- Точки будут в общем линейном положении, что означает, что никакие три точки не являются коллинеарными, и поэтому проходящая через них коника будет уникальной.
- Координаты 5 точек будут десятичными числами от -10 до 10 включительно.
- Точность для десятичных значений / значений с плавающей запятой должна соответствовать точности родного типа float / decimal вашего языка. Если ваш язык / тип данных имеет произвольную точность, вы можете использовать 12 цифр после десятичной точки в качестве максимальной требуемой точности, округляя до нуля (например,
1.0000000000005 == 1.000000000000
). - Капитализация продукции не имеет значения.
- Вывод,
ellipse
когда коническое сечение фактически является кругом, не допускается. Все круги являются эллипсами, но вы должны вывести наиболее конкретный.
По неточностям и точности с плавающей запятой:
Я пытаюсь сделать это как можно проще, чтобы проблемы с неточностями с плавающей запятой не мешали. Цель состоит в том, что если бы тип данных был «магическим значением бесконечной точности» вместо float / double, то все работало бы отлично. Но, поскольку «магического значения бесконечной точности» не существует, вы пишете код, который предполагает, что ваши значения имеют бесконечную точность, и любые проблемы, возникающие в результате неточностей с плавающей запятой, являются особенностями, а не ошибками.
Тестовые случаи
(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
кажется, требуют проверки равенства с плавающей запятой, чтобы отличить их от очень круглого эллипса. Какую точность мы должны принять здесь?Ответы:
Matlab, 154 байта
Сохранено несколько байтов благодаря предложениям Suever.
Принимает вход как
[x1 y1;x2 y2;x3 y3; etc]
. При этом использовалась матрица Вандермонда, и она находит основу своего нулевого пространства, которое всегда будет одним вектором. Затем он вычисляет дискриминант и использует его для создания индекса от 1 до 4, который используется для получения строки.Ungolfed:
sign(...)
Часть вычисляет дискриминант, что дает 1 , если он положительный (гипербола), -1 , если он отрицательный (Эллипс), и 0 , если это 0 (парабола). Вmax(...)
вычитает 1 прочь , если это круг. Массивы Matlab индексируются по одному, поэтому добавьте 3, чтобы получить значения 1, 2, 3, 4, и используйте его для индексации массива имен конических сечений.источник
max() == 0
вы можете упростить до~max()
ones(length(p),1)
тебя можно было сделать1+p(:,1)*0
max()
дело было глупо с моей стороны, у меня были сравнения там прежде и я стал ленивым очевидно! Этот способ получитьones
тоже очень хорошо.JavaScript (ES6), 316
323 347Любой язык, лучше подходящий для работы с матрицей и определителем, должен быть лучше (APL, J, CJAM, Jelly)
Список литературы: Общая форма коники , Пять точек определяют конику , Система линейных уравнений , Определитель
В декартовой плоскости общее уравнение коники
имеющий A или B или C, не равный 0 (в противном случае это прямая линия)
A ... F - шесть неизвестных. С пятью парами (x, y) мы можем построить линейную систему с пятью уравнениями, а масштабирование удалить одно измерение. То есть мы можем установить один из A, B или C в 1, если это не 0 (и мы знаем, что по крайней мере один не равен 0).
Я строю и пытаюсь решить 3 системы: сначала пытаюсь A = 1. Если не решаемо, то B = 1, затем C. (Возможно, есть лучший способ, но в то время это мой лучший вариант)
Имея значения A, B, C, мы можем классифицировать конику, глядя на дискриминант
d=B*B-4*A*C
Меньше гольфа
Тестовое задание
источник
Python - 234 байта
Я никогда не печатать
circle
илиparabola
потому , чтоt
иd[1]
никогда не ударил точно0
, но OP сказал , что все в порядке.источник
С 500
Мой ответ JavaScript перенесен на C. Просто чтобы посмотреть, можно ли это сделать.
Использование: чтение 10 значений из стандартного ввода
Выход:
Тест (идеон)
Меньше гольфа
источник
Sage, 247 байт
Попробуйте онлайн
Эта функция принимает итератор из
(x,y)
пар в качестве входных данных, пытается вычисления дискриминанта каждого из 3 -х возможных линейных систем (A=1
,B=1
иC=1
), и выводит тип конического сечения , основываясь на значениях дискриминанта,A
,B
, иC
.Вероятно, еще предстоит сыграть в гольф, но сейчас я устал от Шалфея и засыпаю, так что утром я над этим поработаю.
источник