Classificare quadrilateri | Aiutami con il mio esame di matematica!


20

Aiuto! Il mio esame di matematica si avvicina presto e non ho studiato! 1 Parte dell'esame è classificare un quadrilatero date le sue coordinate di vertice, che purtroppo non so come fare. 2

Quindi, la tua sfida è quella di scrivere un programma per fare questo per me, quindi non fallisco!

Sfida

Dati quattro vertici in modo tale che tre di essi non siano colorati, determinare la classificazione più specifica del quadrilatero formato da quei quattro vertici.

Quello che intendo per "classificazione più specifica" è che anche se tutti i quadrati sono rettangoli, se la forma è un quadrato, dovresti indicare che è un quadrato e non indicare che è un rettangolo.

Ingresso

L'input verrà dato come quattro (x, y) coordinate. Puoi prenderli come un elenco di lunghezza 4 di elenchi / tuple di lunghezza 2. In alternativa, puoi prendere input come un elenco delle coordinate x e un elenco delle rispettive coordinate y.

Ad esempio, se la mia forma ha i vertici nei punti (0, 0), (5, 0), (6, 1), e (1, 1), si può scegliere di prendere in ingresso in uno dei seguenti formati o qualcosa di simile:

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

Si può presumere che il quadrilatero non sia autointersecante e che i punti siano indicati nell'ordine corretto (ovvero, due punti consecutivi nell'input saranno collegati da un segmento di linea nel quadrilatero).

Produzione

Sarà necessario un output univoco per ciascuna delle seguenti classi di quadrilateri:

  • Piazza
  • Rettangolo
  • Rombo
  • parallelogrammo
  • Trapezio / Trapezio
  • Aquilone
  • Quadrilatero

Questo potrebbe essere il nome esatto stesso, un carattere, un numero intero, ecc.

Regole

  • Si applicano scappatoie standard
  • Se il tuo linguaggio di programmazione ha un built-in che eseguirà questo preciso compito, quel built-in non è permesso.
  • Sono consentiti incorporati per trovare la distanza tra due punti.
  • Sono consentiti incorporati per trovare l'angolo tra due linee.

A questo punto, se conosci tutti i termini, sei pronto per iniziare la programmazione! (I casi di test sono alla fine)

Terminologia

Questa sezione è per chiunque abbia bisogno di chiarimenti sulle definizioni delle diverse forme.

Piazza

Un quadrilatero è un quadrato se e solo se tutti e 4 i suoi lati sono uguali in lunghezza e ogni coppia di lati adiacenti è perpendicolare (cioè è sia un rettangolo che un rombo).

Rettangolo

Un quadrilatero è un rettangolo se e solo se ogni coppia di lati adiacenti è perpendicolare.

Rombo

Un quadrilatero è un rombo se e solo se tutti e 4 i suoi lati sono uguali.

parallelogrammo

Un quadrilatero è un parallelogramma se e solo se ogni coppia di lati opposti è parallela e ogni coppia di angoli opposti è uguale. Entrambe queste condizioni si implicano a vicenda, quindi è necessario verificarne solo una.

Trapezio / Trapezio

Un quadrilatero è un trapezio / trapezio se e solo se ha almeno una coppia di lati paralleli.

Aquilone

Un quadrilatero è un aquilone se due coppie opposte di lati adiacenti sono uguali in lunghezza; cioè due dei suoi lati adiacenti sono uguali e anche gli altri due sono uguali.

Casi test

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

Collegamenti (Desmos Graphing Calculator)

Ecco i collegamenti alle visualizzazioni di ciascuno dei casi di test.

Piazza
rettangolo
Rhombus
parallelogramma
trapezio / Trapezio
Kite
Quadrilatero

Criteri vincenti

Ovviamente non posso portare un computer all'esame, quindi ho bisogno che tu scriva il codice più breve possibile per poterlo memorizzare. Ho bisogno di scriverlo ai margini ed eseguirlo usando TryItOffline TM in modo da adattarlo ai margini che il tuo programma deve essere il più piccolo possibile!

1 Certo che l'ho fatto davvero: P
2 Certo che l'ho fatto davvero: P


1
Potrei essere in grado di aiutarti con il tuo problema di margine xkcd.com/1381
Rohan Jhunjhunwala

@RohanJhunjhunwala Sono il nuovo Fermat (penso che sia la persona giusta?). Ma bello ref XKCD: P
HyperNeutrino il

è consentito l'ingresso CSV?
tuskiomi,

Qual è l'ordine parziale di specificità?
Peter Taylor,

Risposte:


6

APL (Dyalog) , 104 89 80 82 81 79 78 byte

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

Provalo online!


Input Output

Accetta una matrice di coordinate 4 × 2 come input

Uscite

  • 1 1 1 per Square
  • 1 1 0 per Rhombus
  • 1 0 1 per rettangolo
  • 1 0 0 per parallelogramma
  • 1 0 per l'aquilone
  • 0 1 per trapezio
  • 0 0 per quadrilatero

Algoritmo

Innanzitutto, trova tutte le 4 lunghezze laterali e gli angoli del quadrilatero

Se entrambe le coppie di angoli opposti sono uguali ( OA), la forma è una sorta di parallelogramma. Determina se tutte le lunghezze dei lati sono uguali ( AS, i lati adiacenti) e se tutti gli angoli sono uguali ( AA).

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

In caso contrario OA, quindi:

  • Determina se ci sono esattamente 2 coppie di lati adiacenti uguali e se sono separate ( aabbanziché aaab). In tal caso, la forma è un aquilone.

  • Determina se ci sono esattamente 1 coppia di lati opposti paralleli. In tal caso, la forma è un trapezio.

  • Altrimenti, la forma è quadrilatera.


Codice

⍙←{⍵⍺⍺1⌽⍵}definisce un nuovo operatore. In APL, un operatore indica una funzione di ordine superiore . Questo operatore accetta 1 argomento funzionale ( ⍺⍺) e restituisce una funzione monadica che:

  1. Ruota ( 1⌽) l'argomento ( )
  2. Applicare ⍺⍺tra esso e

Ciò è particolarmente utile per le funzioni scalari poiché la maggior parte di esse associa implicitamente argomenti di array, consentendo di applicare quelle tra ciascuna coppia adiacente di elementi con avvolgimento. Ad esempio +⍙1 2 3 4è 1 2 3 4 + 2 3 4 1chi valuta 3 5 7 5.


x←-⍙⎕+.×1 0J1 converte la matrice di coordinate di input in una matrice di numeri complessi che rappresentano i vettori dei 4 lati della forma.

  • , quando indicato, accetta e restituisce input

  • 1 0J1rappresenta il vettore [1, i] ("vettore" in senso matematico e "i" come radice quadrata di -1). In APL, a+biviene scritto un numero complessoaJb

  • +.×moltiplicazione della matrice. Matematicamente, il risultato sarebbe una matrice 4 × 1. Tuttavia, +.×in APL viene chiamato "prodotto interno" che generalizza la moltiplicazione di matrici e il prodotto interno vettoriale e consente di fare anche cose come "moltiplicare" una matrice tridimensionale con una bidimensionale. In questo caso, stiamo moltiplicando una matrice 4 × 2 e un vettore a 2 elementi, risultando in un vettore a 4 elementi (delle rappresentazioni numeriche complesse dei 4 vertici dati).

  • -⍙è la sottrazione a coppie con avvolgimento come indicato sopra. Ciò fornisce i vettori dei 4 lati della forma (come numeri complessi). Questi vettori puntano nella direzione "inversa" ma non importa.

  • x← lo memorizza nella variabile x


2|1+-⍙(12○x)÷○1 trova (una rappresentazione di) gli angoli esterni ai 4 vertici della forma.

  • 12○xtrova l' argomento principale , in radianti, di ciascuno dei 4 vettori laterali.

  • ÷○1si divide per π in modo che gli angoli siano più facili da lavorare. Pertanto, tutti gli angoli sono espressi come un multiplo di un angolo retto.

  • -⍙Sottrazione a coppie con avvolgimento come indicato sopra. Questo dà i 4 angoli esterni.

  • 2|1+ L'argomento principale è limitato (-1,1] e la sottrazione a coppie rende l'intervallo (-2,2]. Ciò è negativo poiché lo stesso angolo ha 2 rappresentazioni diverse. Facendo "aggiungi 1 mod 2", l'angolo viene ri limitato a (0,2]. Anche se tutti gli angoli sono 1 in più di quello che dovrebbe essere, va bene se lo teniamo presente.


|xtrova la grandezza di ciascuno dei 4 vettori laterali


{⍵≡2⌽⍵:≡⍙¨0⍺⍵⋄2 4=+/1=2|+⍙↑⍵(=⍙⍺)}definisce e applica una funzione con l'array di 4 angoli esterni come argomento giusto e l'array di 4 lunghezze laterali come argomento giusto .

  • La funzione ha un'espressione protetta. In questo caso, ⍵≡2⌽⍵è la guardia.
  • Se la guardia valuta 1allora ≡⍙¨0⍺⍵viene eseguita l'espressione successiva e il suo valore restituito.
  • Se la guardia valuta 0, quell'espressione viene saltata e quella successiva 2 4=...=⍙⍺)viene eseguita invece.

⍵≡2⌽⍵ controlla se entrambe le coppie di angoli opposti sono uguali.

  • 2⌽⍵ ruota l'array di angoli di 2 punti.
  • ⍵≡controlla se è uguale a se stesso

≡⍙¨0⍺⍵ restituisce un valore univoco per ciascuna forma di tipo parallelogramma.

  • 0⍺⍵è l'array a 3 elementi dello scalare 0, l'array delle lunghezze laterali e l'array degli angoli .
  • ≡⍙¨esegue ≡⍙per ciascuno di quegli elementi.
  • ≡⍙controlla se tutti i valori di un array sono uguali controllando se ruotandolo di 1 si ottiene lo stesso array. Gli scalari non ruotano, quindi ≡⍙0ritorna 1. Come notato sopra, ≡⍙⍺verifica la presenza di un rombo e ≡⍙⍵verifica la presenza di un rettangolo.

2 4=+/1=2|+⍙↑⍵(=⍙⍺)restituisce un valore univoco per ogni forma di tipo non parallelogramma. Ciò si ottiene intrecciando i controlli per l'aquilone e il trapezio.


2=+/1=2|+⍙⍵ verifica la presenza di un trapezio.

  • +⍙⍵fornisce le somme angolari adiacenti. Gli angoli interni delle linee parallele si sommano ad un angolo retto, così anche gli angoli esterni dei lati paralleli di un quadrilatero. Quindi, ogni coppia di lati paralleli dovrebbe portare a due 1o -1nelle somme angolari adiacenti.

  • 1=2|Tuttavia, gli angoli in sono 1 in più di quello che dovrebbero essere, quindi gli angoli in realtà si sommano a 1o 3. Questo può essere verificato da "mod 2 uguale a 1".

  • +/somma l'array. Ciò fornisce un conteggio delle somme degli angoli adiacenti che è 1o 3.

  • 2= controlla se è uguale a 2. (Vale a dire se esiste esattamente una coppia di lati paralleli)


4=+/1=2|+⍙(=⍙⍺) controlla un aquilone.

  • (=⍙⍺)fornisce un array che indica quali lati adiacenti sono uguali. A differenza del lavoro , dal punto di vista degli =elementi. Quindi, questo è un array di 4 elementi con 1s in cui la lunghezza di quel lato è uguale a quella del lato "successivo".

  • +⍙ Somma a coppie con avvolgimento.

  • 1=2|Poiché (=⍙⍺)fornisce una matrice booleana (una con solo se 0s 1), gli unici valori possibili della somma a coppie sono 0, 1e 2. Quindi 1=2|è come solo 1=.

  • +/somma l'array. Questo dà un conteggio delle somme a coppie che è 1.

  • 4=controlla se è uguale a 4. L'unico modo che succede è se (=⍙⍺)è 1 0 1 0o 0 1 0 1. Come notato sopra, questo significa che la forma è un aquilone.


2 4=+/1=2|+⍙↑⍵(=⍙⍺) intreccia i controlli di cui sopra.

  • ⍵(=⍙⍺)è l'array nidificato a 2 elementi dell'array e dell'array(=⍙⍺)

  • promuove l'array nidificato a una matrice corretta. Poiché ⍵(=⍙⍺)è un array a 2 elementi di array a 4 elementi, il risultato è una matrice 2 × 4.

  • +⍙Poiché (e, per estensione, ) ruota l'ultimo asse (orizzontale), +⍙una matrice è uguale a quella applicata +⍙a ciascuna riga singolarmente.

  • 1=2|sia residue / mod ( |) che equals ( =) funzionano su una base per elemento, anche per le matrici.

  • +/Per impostazione predefinita, reduce ( /) funziona lungo l'ultimo asse (orizzontale). Quindi +/somma lungo le file e trasforma una matrice 2 × 4 in un array semplice a 2 elementi.

  • 2 4=Poiché =funziona per elemento, questo controlla contemporaneamente le condizioni dell'aquilone e del trapezio.


3

Mathematica, 195 byte

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]&

Con spazi bianchi:

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
]&

Uscite 1per quadrati, 2rombi, 3rettangoli, 4parallelogrammi, 5aquiloni, 6trapezi e 7altro. Pubblicherei un link TIO, ma a quanto pare non funziona in matematica.

Se i quattro punti sono P, Q, R, e S, quindi {##,#}viene {P,Q,R,S,P}, quindi sl'elenco dei vettori laterali {Q-P,R-Q,S-R,P-S}, lè la lunghezza di tali vettori, ed rè la condizione che l'angolo tra Q-Pe R-Qcosì come l'angolo tra R-Qe S-Rsono entrambi 90gradi.

Pertanto, se tutte le lunghezze dei lati sono uguali, il quadrilatero è un rombo. Se rregge, in realtà è un quadrato, altrimenti è solo un rombo semplice.

Escludendo i rombi, se entrambe le coppie di lunghezze dei lati opposti sono uguali, il quadrilatero è ancora parallelogramma. Se rregge, in realtà è un rettangolo, altrimenti è solo un semplice parallelogramma.

Escludendo i parallelogrammi, l'elenco delle lunghezze laterali lè della forma {a,b,b,a}o {a,a,b,b}di alcuni ae b, quindi, il quadrilatero è un aquilone. Si noti che non può inoltre essere un trapezio o in realtà sarebbe un rombo.

Escludere parallelogrammi e aquiloni, se il quadrilatero ha una coppia di lati paralleli, allora è un trapezio. Controlliamo ciò Normalizeinging i vettori laterali e controllando se si aggiunge una coppia di vettori opposti {0,0}.

Escludendo tutto quanto sopra, se 1 > 0(è meglio), allora il quadrilatero è solo un vecchio quadrilatero semplice.


1

Python 2 , 463 410 408 397 byte

Hai salvato 53 byte usando una tupla nella sesta riga invece di indicizzarla in un elenco.

Salvato 11 byte spostando gli interi di output da 1 a 7 invece della prima lettera di ogni forma. I numeri interi corrispondono come segue:

  1. Piazza
  2. Rettangolo
  3. Rombo
  4. parallelogrammo
  5. trapezio
  6. Aquilone
  7. Quadrilatero
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

Provalo online!

Ungolfed per mostrare la logica

Indicato come una funzione, per mostrare l'output per i diversi input di test. nota ho cambiato l'esempio di test "Rettangolo" da quello originariamente fornito nella domanda, che non era un rettangolo.

La logica si basa sui prodotti a punti e sulla norma (lunghezza) dei vettori formati dai lati del quadrilatero per valutare se i lati sono uguali in lunghezza, paralleli sui lati opposti o perpendicolari ai lati adiacenti.

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

Provalo online!


1
Classificazione errata [(0, 0), (2, 2), (4, 0), (0,-2)]come aquilone
TwiNight,

Funzionerebbe? repl.it/JRzE
Zacharý

@TwiNight Grazie. Non ho visto questa possibilità. Il problema è che il mio algoritmo iniziale controlla solo se c'è UNA coppia di lati della lunghezza corrispondente. Come mostra l'esempio, non è sufficiente. Avrei bisogno di controllare una coppia di lati abbinati, quindi controllare se anche la coppia opposta ha una lunghezza simile. Sono stato troppo impegnato per implementarlo.
CCB60,

0

Lotto, 287 byte

@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%)

Uscite in binario: 1= Aquilone, 10= Quadrilatero, 11= Trapezio, 100= Parallelogramma, 101= Rombo, 110= Rettangolo, 111= Quadrato. Spiegazione: g, h, i, jsono i quadrati delle lunghezze dei lati.pè il numero di coppie di lati opposti con la stessa lunghezza, qdistingue tra parallelogrammi / rettangoli e rhobmi / quadrati controllando se le coppie opposte sono effettivamente uguali, rdistingue tra parallelogrammi / rombi e rettangoli / quadrati tramite un controllo di perpendicolarità, kverifica la presenza di un aquilone cercando coppie di lati adiacenti uguali e tcontrolli per un trapezio attraverso una coppia di controlli laterali paralleli.



@TwiNight Bah, verificare la presenza di un aquilone è davvero imbarazzante.
Neil,

Sì, sono stato fortunato a trovare un modo compatto per farlo
TwiNight il

@TwiNight Prenderò la tua parola per questo; APL è completamente illeggibile per me.
Neil,

La parte in cui controllo l'aquilone è 2=|-.=⍙⍺. Sicuramente appare compatto se si ignora il lavoro svolto nel calcolo (le 4 lunghezze laterali) e un'intera linea da definire
TwiNight,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.