Классифицировать четырехугольники | Помоги мне с экзаменом по математике!

20

Помогите! Скоро у меня экзамен по математике, а я не учился! 1 Часть экзамена заключается в классификации четырехугольника по координатам его вершин, что я, к сожалению, не знаю, как это сделать. 2

Итак, ваша задача - написать программу, которая сделает это для меня, чтобы я не потерпел неудачу!

Вызов

Учитывая, что четыре вершины таковы, что никакие три из них не являются коллинеарными, определяют наиболее конкретную классификацию четырехугольника, образованного этими четырьмя вершинами.

Под «наиболее конкретной классификацией» я подразумеваю, что, хотя все квадраты являются прямоугольниками, если форма является квадратом, вы должны указать, что это квадрат, а не указывать, что это прямоугольник.

вход

Ввод будет дан в виде четырех (x, y) координат. Вы можете принять их как список длиной 4 из списков / кортежей длины 2. В качестве альтернативы вы можете принять входные данные как список x-координат и список соответствующих y-координат.

Например, если моя форма имеет вершины в точках (0, 0), (5, 0), (6, 1)и (1, 1)вы можете принять вход в любом из следующих форматов или что - то подобное:

[(0, 0), (5, 0), (6, 1), (1, 1)]
([0, 5, 6, 1], [0, 0, 1, 1])

Вы можете предположить, что четырехугольник не является самопересекающимся и что точки заданы в правильном порядке (то есть две последовательные точки на входе будут соединены отрезком в четырехугольнике).

Выход

Вам понадобится уникальный вывод для каждого из следующих классов четырехугольников:

  • Площадь
  • Прямоугольник
  • Ромб
  • Параллелограмм
  • Трапеция / трапеция
  • воздушный змей
  • четырехугольник

Это может быть точное имя, символ, целое число и т. Д.

правила

  • Стандартные лазейки применяются
  • Если ваш язык программирования имеет встроенный модуль, который будет выполнять именно эту задачу, этот встроенный модуль не разрешен.
  • Разрешены встроенные модули для определения расстояния между двумя точками.
  • Разрешены встроенные модули для определения угла между двумя линиями.

На данный момент, если вы знаете все термины, вы готовы начать программирование! (Тестовые случаи в конце)

терминология

Этот раздел для тех, кто нуждается в разъяснении определений различных форм.

Площадь

Четырехугольник является квадратом тогда и только тогда, когда все 4 его стороны равны по длине и каждая пара смежных сторон перпендикулярна (то есть это и прямоугольник, и ромб).

Прямоугольник

Четырехугольник является прямоугольником тогда и только тогда, когда каждая пара смежных сторон перпендикулярна.

Ромб

Четырехугольник является ромбом тогда и только тогда, когда все 4 его стороны равны.

Параллелограмм

Четырехугольник является параллелограммом тогда и только тогда, когда каждая пара противоположных сторон параллельна и каждая пара противоположных углов равна. Оба эти условия подразумевают друг друга, поэтому вам нужно проверить только одно из них.

Трапеция / трапеция

Четырехугольник - это трапеция / трапеция, если и только если она имеет хотя бы одну пару параллельных сторон.

воздушный змей

Четырехугольник - это воздушный змей, если две противоположные пары смежных сторон равны по длине; то есть две смежные стороны равны, а две другие тоже равны.

Тестовые случаи

input as (x, y) * 4 -> full name
[(0, 0), (1, 0), (1, 1), (0, 1)] -> square
[(0, 0), (1, 1), (-1, 3), (-2, 2)] -> rectangle
[(0, 0), (5, 0), (8, 4), (3, 4)] -> rhombus
[(0, 0), (5, 0), (6, 1), (1, 1)] -> parallelogram
[(0, 0), (4, 0), (3, 1), (1, 1)] -> trapezoid/trapezium
[(0, 0), (1, 1), (0, 3), (-1, 1)] -> kite  
[(0, 0), (2, 0), (4, 4), (0, 1)] -> quadrilateral

Ссылки (Графический калькулятор Desmos)

Вот ссылки на визуализации каждого из тестовых случаев.

Квадратный
прямоугольник
ромб
параллелограмм
трапеция / трапеция
змей
четырехугольник

Критерии победы

Я не могу принести компьютер на экзамен, очевидно, поэтому мне нужно, чтобы вы написали максимально короткий код, чтобы я мог его запомнить. Мне нужно записать это в поля и запустить его с помощью TryItOffline TM, чтобы ваша программа была настолько маленькой, насколько это возможно!

1 Конечно я действительно сделал: P
2 Конечно я действительно сделал: P

HyperNeutrino
источник
1
Я мог бы помочь вам с вашей проблемой маржи xkcd.com/1381
Rohan Jhunjhunwala
@RohanJhunjhunwala Я - новый Фермат (я думаю, что это правильный человек?). Но хорошая ссылка XKCD: P
HyperNeutrino
CSV разрешен ввод?
Tuskiomi
Каков частичный порядок специфичности?
Питер Тейлор
Связанные
Цифровая травма

Ответы:

6

APL (Dyalog) , 104 89 80 82 81 79 78 78 байтов

⍙←{⍵⍺⍺1⌽⍵}
⎕←(|x){⍵≡2⌽⍵:≡⍙¨0⍺⍵⋄2 4=+/1=2|+⍙↑⍵(=⍙⍺)}2|1+-⍙(12x←-⍙⎕+.×1 0J1)÷○1

Попробуйте онлайн!


Ввод, вывод

Принимает матрицу координат 4 × 2 в качестве входных данных

Выходы

  • 1 1 1 для площади
  • 1 1 0 для ромба
  • 1 0 1 для прямоугольника
  • 1 0 0 для параллелограмма
  • 1 0 для кайта
  • 0 1 для Трапеции
  • 0 0 для четырехугольника

Алгоритм

Сначала найдите все 4 длины сторон и углы четырехугольника

Если обе пары противоположных углов равны ( OA), то форма является своего рода параллелограммом. Определите, равны ли все длины сторон ( ASсоседние стороны) и равны ли все углы ( AA).

+--------+----------------+----------------+
|        |       AA       |      ~AA       |
+--------+----------------+----------------+
|   AS   |     Square     |    Rhombus     |
|--------+----------------+----------------+
|  ~AS   |    Rectangle   |  Parallelogram |
+--------+----------------+----------------+

Если нет OA, то:

  • Определите, есть ли ровно 2 пары равных смежных сторон и разделены ли они ( aabbвместо aaab). Если это так, форма является воздушным змеем.

  • Определите, есть ли ровно 1 пара параллельных противоположных сторон. Если это так, то форма трапеции.

  • В противном случае форма является четырехугольной.


Код

⍙←{⍵⍺⍺1⌽⍵}определяет новый оператор. В APL оператор означает функцию более высокого порядка . Этот оператор принимает 1 функциональный аргумент ( ⍺⍺) и возвращает монадическую функцию, которая:

  1. Поворачивает ( 1⌽) аргумент ( )
  2. Применить ⍺⍺между этим и

Это особенно полезно для скалярных функций, так как большинство из них неявно отображаются в аргументах массива, что позволяет применять их между каждой соседней парой элементов с переносом. Например +⍙1 2 3 4, 1 2 3 4 + 2 3 4 1который оценивает 3 5 7 5.


x←-⍙⎕+.×1 0J1 преобразует матрицу входных координат в массив комплексных чисел, представляющих векторы четырех сторон фигуры.

  • при ссылке принимает и возвращает ввод

  • 1 0J1представляет вектор [1, i] («вектор» в математическом смысле, а «i» - квадратный корень из -1). В APL a+biнаписано комплексное числоaJb

  • +.×умножение матриц. Математически, результатом будет матрица 4 × 1. Однако +.×в APL он называется «внутренним произведением», которое обобщает умножение матриц и векторное внутреннее произведение и позволяет вам даже выполнять такие вещи, как «умножение» 3-мерного массива на 2-мерный. В этом случае мы умножаем матрицу 4 × 2 и 2-элементный вектор, в результате чего получается 4-элементный вектор (из представлений комплексных чисел 4 заданных вершин).

  • -⍙парное вычитание с переносом, как отмечено выше. Это дает векторы 4 сторон фигуры (в виде комплексных чисел). Эти векторы указывают в «обратном» направлении, но это не имеет значения.

  • x← сохраняет это в переменную x


2|1+-⍙(12○x)÷○1 находит (представление) внешние углы в 4 вершинах фигуры.

  • 12○xнаходит основной аргумент в радианах каждого из 4 боковых векторов.

  • ÷○1делит на π, чтобы с углами было легче работать. Таким образом, все углы выражаются в виде кратного прямого угла.

  • -⍙Парное вычитание с переносом, как отмечено выше. Это дает 4 внешних угла.

  • 2|1+ Главный аргумент ограничен (-1,1], а парное вычитание создает диапазон (-2,2]. Это плохо, поскольку один и тот же угол имеет 2 разных представления. При выполнении «добавить 1 мод 2» угол ограничено (0,2). Хотя все углы на 1 больше, чем должно быть, хорошо, если мы будем помнить об этом.


|xнаходит величину каждого из 4 боковых векторов


{⍵≡2⌽⍵:≡⍙¨0⍺⍵⋄2 4=+/1=2|+⍙↑⍵(=⍙⍺)}определяет и применяет функцию с массивом из 4 внешних углов в качестве правого аргумента и с массивом из 4 длин сторон в качестве правого аргумента .

  • Функция имеет защищенное выражение. В данном случае ⍵≡2⌽⍵это охранник.
  • Если значение параметра guard равно значению, выполняется 1следующее выражение ≡⍙¨0⍺⍵и возвращается его значение.
  • Если гвардия оценивает 0, это выражение пропускается, и 2 4=...=⍙⍺)вместо него выполняется то, что после .

⍵≡2⌽⍵ проверяет, равны ли обе пары противоположных углов.

  • 2⌽⍵ вращает массив углов на 2 места.
  • ⍵≡проверяет, совпадает ли это с самим собой

≡⍙¨0⍺⍵ возвращает уникальное значение для каждой фигуры типа параллелограмма.

  • 0⍺⍵3-элементный массив скаляров 0, массив боковых длин и массив углов .
  • ≡⍙¨выполняется ≡⍙для каждого из этих элементов.
  • ≡⍙проверяет, все ли значения массива равны, проверяя, дает ли поворот его на 1 одинаковый массив. Скаляры не вращаются, поэтому ≡⍙0возвращается 1. Как отмечено выше, ≡⍙⍺проверяет наличие ромба и ≡⍙⍵проверяет наличие прямоугольника.

2 4=+/1=2|+⍙↑⍵(=⍙⍺)возвращает уникальное значение для каждой фигуры непараллелограммного типа. Это достигается путем переплетения проверок кайта и трапеции.


2=+/1=2|+⍙⍵ проверяет трапецию.

  • +⍙⍵дает смежные угловые суммы. Внутренние углы параллельных линий суммируются в прямой угол, так же как и внешние углы параллельных сторон четырехугольника. Итак, каждая пара параллельных сторон должна приводить к двум 1или -1к смежным угловым суммам.

  • 1=2|Тем не менее, углы на 1 больше, чем они должны быть, поэтому углы на самом деле составляют 1или 3. Это можно проверить с помощью «mod 2 равно 1».

  • +/суммирует массив. Это дает счетчик смежных угловых сумм, который равен 1или 3.

  • 2= проверить, равно ли это 2. (т. е. если есть ровно одна пара параллельных сторон)


4=+/1=2|+⍙(=⍙⍺) проверяет наличие воздушного змея

  • (=⍙⍺)дает массив, указывающий, какие смежные стороны равны В отличие , =работа поэлементно. Таким образом, это 4-элементный массив с 1s, где длина этой стороны равна длине "следующей" стороны.

  • +⍙ Попарная сумма с обтеканием.

  • 1=2|Так как (=⍙⍺)дает логический массив (один только 0с s и 1s), единственно возможными значениями попарной суммы являются 0, 1и 2. Так 1=2|же, как и просто 1=.

  • +/суммирует массив. Это дает счет попарных сумм, который есть 1.

  • 4=проверьте, что равняется 4. Единственный способ , что происходит, если (=⍙⍺)есть 1 0 1 0или 0 1 0 1. Как отмечено выше, это означает, что форма представляет собой воздушный змей.


2 4=+/1=2|+⍙↑⍵(=⍙⍺) переплетает вышеупомянутые проверки.

  • ⍵(=⍙⍺)является 2-элементным вложенным массивом массива и массива(=⍙⍺)

  • переводит вложенный массив в правильную матрицу. Поскольку ⍵(=⍙⍺)это 2-элементный массив из 4-элементных массивов, результатом является матрица 2 × 4.

  • +⍙Поскольку (и, соответственно, ) вращает последнюю (горизонтальную) ось, +⍙матрица такая же, как и +⍙для каждой строки в отдельности.

  • 1=2|оба rema / mod ( |) и equals ( =) работают для каждого элемента отдельно, даже для матриц.

  • +/По умолчанию, limit ( /) работает вдоль последней (горизонтальной) оси. Таким образом, +/суммируем вдоль строк и превращаем матрицу 2 × 4 в простой 2-элементный массив.

  • 2 4=Так как =работает для каждого элемента, это проверяет условия кайта и трапеции одновременно.

TwiNight
источник
3

Mathematica, 195 байт

Which[s=Differences@{##,#};l=Norm/@s;r=#.#2==#2.#3==0&@@s;Equal@@l,If[r,1,2],#==#3&&#2==#4&@@l,If[r,3,4],MatchQ[l,{a_,b_,b_,a_}|{a_,a_,b_,b_}],5,#+#3=={0,0}||#2+#4=={0,0}&@@Normalize/@s,6,1>0,7]&

С пробелами:

Which[
    s = Differences @ {##,#};
    l = Norm /@ s;
    r = #.#2 == #2.#3 == 0& @@ s;

    Equal @@ l, If[r, 1, 2],
    # == #3 && #2 == #4& @@ l, If[r, 3, 4],
    MatchQ[l, {a_,b_,b_,a_}|{a_,a_,b_,b_}], 5,
    #+#3 == {0,0} || #2+#4 == {0,0}& @@ Normalize /@ s, 6,
    1 > 0, 7
]&

Выходы 1для квадратов, 2для ромбов, 3для прямоугольников, 4для параллелограммов, 5для воздушных змеев, 6для трапеций и 7для чего-либо еще. Я бы опубликовал ссылку TIO, но это, очевидно, не работает в математике.

Если четыре точки P, Q, R, и S, затем {##,#}будет {P,Q,R,S,P}, поэтому sсписок боковых векторов {Q-P,R-Q,S-R,P-S}, lявляется длины этих векторов, и rявляется условием , что угол между Q-Pи R-Qтак же , как и угол между R-Qи S-Rоба 90градусов.

Таким образом, если длины всех сторон равны, то четырехугольник является ромбом. Если rимеет место, это на самом деле квадрат, в противном случае это просто ромб.

Исключая ромбы, если обе пары противоположных длин сторон равны, то четырехугольник все еще параллелограмм. Если rвыполнено, это на самом деле прямоугольник, в противном случае это просто параллелограмм.

Исключая параллелограммы, список длин сторон lимеет форму {a,b,b,a}или {a,a,b,b}для некоторых, aа bзатем четырехугольник является воздушным змеем. Обратите внимание, что это не может быть трапеция или ромб.

Исключая параллелограммы и воздушных змеев, если у четырехугольника есть пара параллельных сторон, то это трапеция. Мы проверяем это, Normalizeиспользуя боковые векторы и проверяя, добавляет ли пара противоположных векторов {0,0}.

Исключая все вышеперечисленное, если 1 > 0(лучше), то четырехугольник просто старый четырехугольник.

ngenisis
источник
1

Python 2 , 463 410 408 397 байт

Сохранено 53 байта с помощью кортежа в шестой строке вместо индексации в списке.

Сохранено 11 байтов путем сдвига в выходные целые числа от 1 до 7 вместо первой буквы каждой фигуры. Целые числа соответствуют следующим образом:

  1. Площадь
  2. Прямоугольник
  3. Ромб
  4. Параллелограмм
  5. трапеция
  6. воздушный змей
  7. четырехугольник
from numpy import *;D=dot
from numpy.linalg import *;N=norm
def P(a,b):x=D(a,b);y=N(a)*N(b);return x==y or x==-y
def Q(a,b):return int(N(a)==N(b))
L=input()
a,b,c,d=tuple([(L[i][0]-L[(i+1)%4][0],L[i][1]-L[(i+1)%4][1]) for i in range(4)])
g=7
e=Q(a,c)+Q(b,d)
if e==2:
 g=(1if D(a,b)==0 else 3) if Q(a,b) else 2 if D(a,b)==0 else 4
elif P(a,c) or P(b,d):
 g = 5
elif Q(a,b) or Q(b,c):
 g = 6
print g

Попробуйте онлайн!

Неуправляемый, чтобы показать логику

Показан как функция, чтобы показать выходные данные для различных тестовых входных данных. Обратите внимание, что я изменил пример теста "Прямоугольник" с того, который изначально был представлен в вопросе, который не был прямоугольником.

Логика основывается на точечных произведениях и норме (длине) векторов, образованных сторонами четырехугольника, чтобы оценить, равны ли стороны по длине, параллельны ли на противоположных сторонах или перпендикулярны соседним сторонам.

def S(va, vb):
    return (va[0]-vb[0], va[1]-vb[1])
def dot(sa,sb):      # Eventually replaced with numpy.dot
    return(sa[0]*sb[0]+sa[1]*sb[1])
def norm(s):         # Eventually replaced by numpy.linalg.norm
    return (s[0]**2+s[1]**2)**.5
def isperp(a,b):     # Test if lines/vectors are perpendicular
    return dot(a,b)==0
def ispar(a,b):      # Test if lines/vectors are parallel
    x = dot(a,b)
    y = norm(a)*norm(b)
    return x == y or x == -y
def iseq(a,b):       # Test if lines/vectors are equal in length
    return norm(a)==norm(b)
   
def f(L):
    #Define the four sides
    s = []
    for i in range(4):
        s.append(S(L[i],L[(i+1)%4]))  # I refer often so shorter names may eventually

    guess = 'Q'
    eqsides = 0           # These 6 lines eventually golfed using integer arithmetic by returning an int from iseq()
    if iseq(s[0], s[2]):
        eqsides += 1
    if iseq(s[1],s[3]):
        eqsides += 1
    if eqsides == 2:
    # Opposite sides are equal, so square, rhombus, rectangle or parallelogram
        if iseq(s[0],s[1]):       #Equal adjacent sides, so square or rhombus
            guess='S' if isperp(s[0], s[1]) else 'H'
        else:                     # rectangle or Parallelogram
            guess='R' if isperp(s[0], s[1]) else 'P'
    elif ispar(s[0],s[2]) or ispar(s[1],s[3]):
        guess = 'T'
    elif iseq(s[0],s[1]) or iseq(s[1],s[2]):
        guess = 'K'
    return guess
    

#test suite:
print f([(0, 0), (1, 0), (1, 1), (0, 1)]) # -> square
print f([(0, 0), (1, 1), (-1, 3), (-2, 2)]) # -> rectangle
print f([(0, 0), (5, 0), (8, 4), (3, 4)]) #  -> rhombus
print f([(0, 0), (5, 0), (6, 1), (1, 1)]) #  -> parallelogram
print f([(0, 0), (4, 0), (3, 1), (1, 1)]) # -> trapezoid/trapezium
print f([(0, 0), (1, 1), (0, 3), (-1, 1)]) #-> kite  
print f([(0, 0), (2, 0), (4, 4), (0, 1)]) #-> quadrilateral

Попробуйте онлайн!

CCB60
источник
1
Misclassified [(0, 0), (2, 2), (4, 0), (0,-2)]как воздушный змей
TwiNight
Будет ли это работать? repl.it/JRzE
Zacharý
@TwiNight Спасибо. Не видел такой возможности. Проблема в том, что мой первоначальный алгоритм только проверяет, есть ли ОДНА пара сторон совпадающей длины. Как показывает ваш пример, этого недостаточно. Мне нужно проверить наличие одной пары совпадающих сторон, а затем проверить, одинаковы ли длина противоположной пары. Был слишком занят, чтобы реализовать это.
CCB60
0

Пакетный, 287 байт

@set/aa=%3-%1,b=%4-%2,c=%5-%1,d=%6-%2,e=%7-%1,f=%8-%2,g=a*a+b*b,h=(h=c-a)*h+(h=d-b)*h,i=(i=c-e)*i+(i=d-f)*i,j=e*e+f*f,p=!(i-g)+!(j-h),q=!(h-g),r=!(a*e+b*f),k=q+!(j-i)^|!(j-g)+!(h-i),t=!(a*(f-d)-b*(e-c))+!((c-a)*f-(d-b)*e)
@if %p%==2 (echo 1%r%%q%)else if %k%==2 (echo 1)else (echo 1%t%)

Выходы в двоичном виде: 1= воздушный змей, 10= четырехугольник, 11= трапеция, 100= параллелограмм, 101= ромб, 110= прямоугольник, 111= квадрат. Пояснение: g, h, i, jэто квадраты длин сторон. p- это число пар противоположных сторон одинаковой длины. qРазличает параллелограммы / прямоугольники и ромбы / квадраты, проверяя, равны ли на самом деле противоположные пары, rразличает параллелограммы / ромбы и прямоугольники / квадраты с помощью проверки перпендикулярности, kпроверяет наличие кайт, ища пары равных соседних сторон и tпроверяет трапецию через пару параллельных боковых проверок.

Нил
источник
Смотрите этот комментарий
TwiNight
@TwiNight Бах, проверка на змея действительно неловко.
Нил
Да, мне повезло найти компактный способ сделать это
TwiNight
@TwiNight Я верю твоему слову; APL совершенно нечитаем для меня.
Нил
Часть, где я проверяю на кайт 2=|-.=⍙⍺. Конечно, выглядит компактно, если вы игнорируете работу, положенную в расчет (4 стороны длины) и целую строку для определения
TwiNight