Класифікуйте чотирикутники | Допоможіть мені з моїм іспитом з математики!


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


1
Я можу допомогти вам у вирішенні вашої проблеми з маржами xkcd.com/1381
Rohan Jhunjhunwala

@RohanJhunjhunwala Я - новий Фермат (я думаю, це правильна людина?). Але приємний XKCD ref: P
HyperNeutrino

чи дозволено введення CSV?
тускіоми

Що таке частковий порядок специфіки?
Пітер Тейлор

Відповіді:


6

APL (Діалог) , 104 89 80 82 81 79 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 перетворює вхідну матрицю координат у масив складних чисел, що представляють вектори з 4 сторін форми.

  • , при посиланні приймає та повертає вхідні дані

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

  • +.×матричне множення. Математично результат отримав би матрицю 4 × 1. Однак +.×у APL називається "внутрішнім продуктом", який узагальнює множення матриць та внутрішній векторний векторний продукт і дозволяє робити навіть такі речі, як "помножити" 3-мірний масив з двовимірним. У цьому випадку ми множимо матрицю 4 × 2 та 2-елементний вектор, у результаті чого виходить 4-елементний вектор (із складних представлень чисел із 4 заданих вершин).

  • -⍙- парне віднімання з обгортанням, як зазначено вище. Це дає вектори 4 сторін форми (як складні числа). Ці вектори вказують у зворотному напрямку, але це не має значення.

  • x← зберігає це в змінну x


2|1+-⍙(12○x)÷○1 знаходить (зображення) зовнішніх кутів у 4 вершинах фігури.

  • 12○xзнаходить головний аргумент у радіанах кожного з чотирьох бічних векторів.

  • ÷○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⌽⍵стоїть охоронець.
  • Якщо охоронець оцінює, 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з і 1с), можливим тільки значенням суми попарно є 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|і залишок / mod ( |), і equals ( =) працює на основі елемента, навіть для матриць.

  • +/За замовчуванням функція Redu ( /) працює уздовж останньої (горизонтальної) осі. Таким чином, +/підсумовуйте уздовж рядків і перетворіть матрицю 2 × 4 в 2-елементний простий масив.

  • 2 4=Оскільки =працює на елемент, це перевіряє умови кайта та трапеції одночасно.


3

Математика, 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, але це, мабуть, не працює в Mathics.

Якщо чотири точки 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(краще буде), то чотирикутник - це просто звичайний старий чотирикутник.


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

Спробуйте в Інтернеті!


1
[(0, 0), (2, 2), (4, 0), (0,-2)]
Помірно

Це би спрацювало? 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 Bah, перевірити змій справді незручно.
Ніл

Так, мені пощастило знайти компактний спосіб зробити це
TwiNight

@TwiNight Я візьму за це ваше слово; APL для мене абсолютно нечитабельна.
Ніл

Частина, де я перевіряю на змій - це 2=|-.=⍙⍺. Звичайно, це виглядає компактно, якщо ви ігноруєте роботу, обчислену (4 бічні довжини) та цілу лінію для визначення
TwiNight
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.