Проблема счастливого конца (на самом деле теорема) утверждает, что
Любое множество из пяти точек на плоскости общего положения имеет подмножество из четырех точек, которые образуют вершины выпуклого четырехугольника.
Эта проблема была названа Полом Эрдосом, когда два математика, которые первыми работали над этой проблемой, Эстер Кляйн и Джордж Секерес, обручились и впоследствии поженились.
Разъяснения:
- Общее положение здесь означает, что никакие три точки не являются коллинеарными.
Четырехугольник, образованный четырьмя вершинами, всегда будет считаться непересекающимся, независимо от порядка точек. Например, если четыре точки
[1 1]
,[1 2]
,[2 1]
,[2 2]
предполагаемый четырехугольник является квадратом, а не бантик:Непересекающийся четырехугольник является выпуклым, если внутренний угол не превышает 180 градусов; или эквивалентно, если обе диагонали лежат внутри четырехугольника.
Соревнование
Учитывая 5 точек с положительными целочисленными координатами, выведите 4 из тех точек, которые образуют выпуклый четырехугольник.
правила
Если существует несколько решений (то есть несколько наборов из 4 точек), вы можете последовательно выбрать вывод одного из них или всех.
Форматы ввода и вывода, как обычно, гибкие (массивы, списки, список списков, строки с разумными разделителями и т. Д.).
Код гольф, побеждает меньше байтов.
Контрольные примеры
Входные данные:
[6 8] [1 10] [6 6] [5 9] [8 10]
Возможен только один выход:
[6 8] [1 10] [6 6] [5 9]
Входные данные:
[3 8] [7 5] [6 9] [7 8] [5 1]
Есть пять решений:
[3 8] [7 5] [6 9] [7 8] [3 8] [7 5] [6 9] [5 1] [3 8] [7 5] [7 8] [5 1] [3 8] [6 9] [7 8] [5 1] [7 5] [6 9] [7 8] [5 1]
Входные данные:
[4 8] [1 9] [9 9] [10 2] [1 6]
Есть три решения:
[4 8] [1 9] [10 2] [1 6] [4 8] [9 9] [10 2] [1 6] [1 9] [9 9] [10 2] [1 6]
Чтобы проиллюстрировать, вот три решения этого случая:
Ответы:
CJam,
373432 байтаНе уверен, достаточно ли
:-V
счастлив, но, как указывает К. Чжан,=}
в конце есть. :)Это печатает только одно решение, потому что удаление дубликатов будет дороже.
Проверьте это здесь.
объяснение
Идея довольно проста. Мы генерируем все возможные четырехугольники (включая все упорядочения точек), а затем просто выбираем выпуклые. Мы проверяем выпуклость, просматривая каждую пару ребер и проверяя, все ли они вращаются в одном направлении.
Чувство поворота может быть легко получено из точечного произведения. Если вы возьмете три последовательные точки на четырехугольнике и проведете линии от первого ко второму и с первого по третий, а затем спроецируете последние на перпендикуляр первого ... вы получите число, знак которого говорит вам повернуть ли эти три точки влево или вправо. (Я, вероятно, должен добавить диаграмму для этого.) Это «проецирование на перпендикуляр» звучит довольно сложно, но на самом деле это просто означает, что мы переворачиваем один из двух векторов и вычитаем компоненты после умножения, а не добавляем их. Итак, вот код ...
источник
!}
тоже можно было бы подмигнутьMATLAB, 67 байт
Входные данные представлены в виде 2D-матрицы, в которой столбцами являются X и Y соответственно:
Все наборы из 4 точек, которые создают выпуклые четырехугольники, отображаются в одном формате.
Вот демо , которое немного модифицировано для работы с Octave
объяснение
Это решение принимает все подмножества 4 точек ввода (порядок не имеет значения). Для этого мы создаем единичную матрицу и его отрицания:
~eye(5)
. Мы перебираем столбцы этой матрицы иk
(индекс цикла) представляет собой логический массив, который указывает, какую из 4 точек следует учитывать. Затем мы используем это, чтобы получить эти 4 точки XY из input (I(k,:)
).Затем мы вычисляем выпуклую оболочку этих 4 точек (
convhull
). Выходными даннымиconvhull
являются индексы входных данных, которые соответствуют точкам, составляющим выпуклую оболочку (с первым дублированным индексом, чтобы закрыть корпус).Для выпуклого четырехугольника все четыре точки будут частью выпуклой оболочки одних и тех же точек (
nnz(convhull(points)) > 4
). Если мы обнаружим, что это так, мы отобразим точки, которые были использованы для этой конкретной итерации.источник
Javascript (ES6),
306293283 байтаПояснение :
Функция
c
вычисляет перекрестное произведение вектора между 3 смежными точками многоугольника и возвращает 1, если оно положительное, и 0 в противном случае (примечание: перекрестное произведение не может быть нулевым, поскольку точки не могут быть коллинеарными).Функция
k
иj
генерирует все циклические перестановки (игнорируя изменение порядка) входного массива.Затем вызывается функция 'i' для каждой циклической перестановки, чтобы вычислить сумму функции
c
для каждого из 4 триплетов смежных координат. Если все перекрестные произведения имеют один и тот же знак, то все они будут равны 0 или 1 и будут равны 0 (по модулю 4), а многоугольник будет вогнутым и помещается в выходной массив. Если любой триплет имеет другой знак, тогда сумма будет отлична от нуля (по модулю 4), а многоугольник выпуклый.Функция
f
используется для инициализации выходного массива, а затем вызывает вышеуказанные функции перед возвратом выходных данных.Тесты :
Редактировать :
Может также обрабатывать коллинеарные точки, используя оригинальную версию и изменяя первые две строки на:
Однако, поскольку этот случай специально исключен в вопросе, дополнительные символы не нужны.
источник
Mathematica
10596 байтSelect[#~Subsets~{4},f@#&]&
выбирает из списка (5) баллов те подмножества из 4 баллов, которые удовлетворяютf
.f
выполняется, когда каждая из четырех точек в наборе лежит наRegionBoundary
однойConvexHull
из четырех точек.Тестовые случаи
1. Давайте рассмотрим 5 выпуклых оболочек подмножеств (каждая из 4 точек) {{6, 8}, {1, 10}, {6, 6}, {5, 9}, {8, 10}} ,
{{{6, 8}, {1, 10}, {6, 6}, {5, 9}}}
{{6, 8}, {1, 10}, {6, 6}, {5, 9}} - единственное решение; каждая из четырех точек служит вершиной выпуклой оболочки (из тех же 4 точек).
{{6, 8}, {1, 10}, {6, 6}, {8, 10}} не является решением; выпуклая оболочка имеет только 3 вершины. {6, 8} лежит внутри корпуса.
Остальные подмножества также не являются решениями:
2. {{4, 8}, {1, 9}, {9, 9}, {10, 2}, {1, 6}} имеет три решения.
{
{{4, 8}, {1, 9}, {10, 2}, {1, 6}},
{{4, 8}, {9, 9}, {10, 2}, {1, 6 }},
{{1, 9}, {9, 9}, {10, 2}, {1, 6}}
}
3. {{3, 8}, {7, 5}, {6, 9}, {7, 8}, {5, 1}} имеет 5 решений.
{
{{3, 8}, {7, 5}, {6, 9}, {7, 8}},
{{3, 8}, {7, 5}, {6, 9}, {5, 1 }},
{{3, 8}, {7, 5}, {7, 8}, {5, 1}},
{{3, 8}, {6, 9}, {7, 8}, {5 , 1}},
{{7, 5}, {6, 9}, {7, 8}, {5, 1}}
}
Отметим, что каждая из пяти точек лежит на границе выпуклой оболочки всех точек.
Если какая-либо из точек будет удалена, оставшиеся 4 точки будут вершинами уменьшенной выпуклой оболочки.
источник