Classer les quadrilatères | Aidez-moi avec mon examen de mathématiques!


20

Aidez-moi! Mon examen de mathématiques arrive bientôt et je n'ai pas étudié! 1 Une partie de l'examen consiste à classer un quadrilatère en fonction de ses coordonnées de sommets, ce que je ne sais malheureusement pas faire. 2

Donc, votre défi est d'écrire un programme pour le faire pour que je n'échoue pas!

Défi

Étant donné quatre sommets tels qu'aucun d'eux ne soit colinéaire, déterminez la classification la plus spécifique du quadrilatère formé par ces quatre sommets.

Ce que je veux dire par "classification la plus spécifique", c'est que même si tous les carrés sont des rectangles, si la forme est un carré, vous devez indiquer qu'il s'agit d'un carré et non indiquer qu'il s'agit d'un rectangle.

Contribution

L'entrée sera donnée sous forme de quatre (x, y) coordonnées. Vous pouvez les prendre comme une liste de longueur 4 de listes / tuples de longueur 2. Alternativement, vous pouvez prendre l'entrée comme une liste des coordonnées x et une liste des coordonnées y respectives.

Par exemple, si ma forme a des sommets aux points (0, 0), (5, 0), (6, 1)et (1, 1), vous pouvez choisir de prendre l' entrée dans l'un des formats suivants ou quelque chose de similaire:

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

Vous pouvez supposer que le quadrilatère n'est pas auto-intersecté et que les points sont donnés dans le bon ordre (c'est-à-dire que deux points consécutifs dans l'entrée seront connectés par un segment de ligne dans le quadrilatère).

Production

Vous aurez besoin d'une sortie unique pour chacune des classes de quadrilatères suivantes:

  • Carré
  • Rectangle
  • Rhombe
  • Parallélogramme
  • Trapèze / Trapèze
  • Kite
  • Quadrilatère

Cela pourrait être le nom exact lui-même, un caractère, un entier, etc.

Règles

  • Les échappatoires standard s'appliquent
  • Si votre langage de programmation a un intégré qui effectuera cette tâche exacte, ce intégré n'est pas autorisé.
  • Les fonctions intégrées pour trouver la distance entre deux points sont autorisées.
  • Les fonctions intégrées pour trouver l'angle entre deux lignes sont autorisées.

À ce stade, si vous connaissez tous les termes, vous êtes prêt à commencer la programmation! (Les cas de test sont à la fin)

Terminologie

Cette section s'adresse à toute personne qui a besoin d'éclaircissements sur les définitions des différentes formes.

Carré

Un quadrilatère est un carré si et seulement si ses 4 côtés sont égaux en longueur et que chaque paire de côtés adjacents est perpendiculaire (c'est-à-dire à la fois un rectangle et un losange).

Rectangle

Un quadrilatère est un rectangle si et seulement si chaque paire de côtés adjacents est perpendiculaire.

Rhombe

Un quadrilatère est un losange si et seulement si ses 4 côtés sont égaux.

Parallélogramme

Un quadrilatère est un parallélogramme si et seulement si chaque paire de côtés opposés est parallèle et chaque paire d'angles opposés est égale. Ces deux conditions s’impliquent mutuellement, il vous suffit donc de vérifier l’une d’elles.

Trapèze / Trapèze

Un quadrilatère est un trapèze / trapèze si et seulement s'il a au moins une paire de côtés parallèles.

Kite

Un quadrilatère est un cerf-volant si deux paires opposées de côtés adjacents sont de longueur égale; c'est-à-dire que deux de ses côtés adjacents sont égaux et les deux autres sont également égaux.

Cas de 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

Liens (Calculatrice graphique Desmos)

Voici des liens vers des visualisations de chacun des cas de test.


Rectangle carré
losange
parallélogramme
trapézoïde / trapèze
cerf-volant
quadrilatère

Critères gagnants

Je ne peux évidemment pas apporter un ordinateur à l'examen, j'ai donc besoin que vous écriviez le code le plus court possible pour pouvoir le mémoriser. Je dois l'écrire dans les marges et l'exécuter en utilisant TryItOffline TM afin de l'adapter aux marges, votre programme doit être aussi petit que possible!

1 Bien sûr, j'ai fait: P
2 Bien sûr, j'ai fait: P


1
Je pourrai peut-être vous aider avec votre problème de marge xkcd.com/1381
Rohan Jhunjhunwala

@RohanJhunjhunwala Je suis le nouveau Fermat (je pense que c'est la bonne personne?). Mais belle référence XKCD: P
HyperNeutrino

l'entrée CSV est-elle autorisée?
tuskiomi

Quel est l'ordre partiel de spécificité?
Peter Taylor

Réponses:


6

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

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

Essayez-le en ligne!


Entrée sortie

Prend une matrice de coordonnées 4 × 2 en entrée

Les sorties

  • 1 1 1 pour Square
  • 1 1 0 pour Rhombus
  • 1 0 1 pour Rectangle
  • 1 0 0 pour parallélogramme
  • 1 0 pour Kite
  • 0 1 pour Trapezium
  • 0 0 pour quadrilatère

Algorithme

Tout d'abord, trouvez les 4 longueurs et angles latéraux du quadrilatère

Si les deux paires d'angles opposés sont égales ( OA), alors la forme est une sorte de parallélogramme. Déterminez si toutes les longueurs de côté sont égales ( AS, côtés adjacents) et si tous les angles sont égaux ( AA).

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

Sinon OA, alors:

  • Déterminez s'il y a exactement 2 paires de côtés adjacents égaux et s'ils sont séparés ( aabbau lieu de aaab). Si c'est le cas, la forme est un cerf-volant.

  • Déterminez s'il y a exactement 1 paire de côtés opposés parallèles. Si c'est le cas, la forme est un trapèze.

  • Sinon, la forme est un quadrilatère.


Code

⍙←{⍵⍺⍺1⌽⍵}définit un nouvel opérateur. En APL, un opérateur signifie une fonction d'ordre supérieur . Cet opérateur prend 1 argument fonctionnel ( ⍺⍺) et retourne une fonction monadique qui:

  1. Tourne ( 1⌽) l'argument ( )
  2. Appliquer ⍺⍺entre elle et

Ceci est particulièrement utile pour les fonctions scalaires car la plupart d'entre elles sont implicitement mappées sur des arguments de tableau, permettant d'appliquer ceux entre chaque paire d'éléments adjacents avec bouclage. Par exemple +⍙1 2 3 4est 1 2 3 4 + 2 3 4 1qui évalue à 3 5 7 5.


x←-⍙⎕+.×1 0J1 convertit la matrice de coordonnées d'entrée en un tableau de nombres complexes représentant les vecteurs des 4 côtés de la forme.

  • , lorsqu'il est référencé, prend et renvoie une entrée

  • 1 0J1représente le vecteur [1, i] ("vecteur" au sens mathématique et "i" comme racine carrée de -1). En APL, un nombre complexe a+biest écritaJb

  • +.×multiplication matricielle. Mathématiquement, le résultat serait une matrice 4 × 1. Cependant, +.×est appelé "produit intérieur" dans APL qui généralise la multiplication matricielle et le produit intérieur vectoriel et vous permet de faire même des choses comme "multiplier" un tableau à 3 dimensions avec un tableau à 2 dimensions. Dans ce cas, nous multiplions une matrice 4 × 2 et un vecteur à 2 éléments, résultant en un vecteur à 4 éléments (des représentations de nombres complexes des 4 sommets donnés).

  • -⍙est une soustraction par paire avec enroulement comme indiqué ci-dessus. Cela donne les vecteurs des 4 côtés de la forme (sous forme de nombres complexes). Ces vecteurs pointent dans le sens "inverse" mais cela n'a pas d'importance.

  • x← stocke cela dans la variable x


2|1+-⍙(12○x)÷○1 trouve (une représentation de) les angles extérieurs aux 4 sommets de la forme.

  • 12○xtrouve l' argument principal , en radians, de chacun des 4 vecteurs latéraux.

  • ÷○1divise par π pour que les angles soient plus faciles à travailler. Ainsi, tous les angles sont exprimés comme un multiple d'un angle droit.

  • -⍙Soustraction par paire avec enroulement comme indiqué ci-dessus. Cela donne les 4 angles extérieurs.

  • 2|1+ L'argument principal est plafonné (-1,1] et la soustraction par paire fait la plage (-2,2]. C'est mauvais car le même angle a 2 représentations différentes. En faisant "ajouter 1 mod 2", l'angle est re plafonné à (0,2]. Bien que tous les angles soient 1 de plus que ce qu'il devrait être, c'est bien si nous gardons cela à l'esprit.


|xtrouve la grandeur de chacun des 4 vecteurs latéraux


{⍵≡2⌽⍵:≡⍙¨0⍺⍵⋄2 4=+/1=2|+⍙↑⍵(=⍙⍺)}définit et applique une fonction avec le tableau de 4 angles extérieurs comme argument de droite et le tableau de 4 longueurs de côté comme argument de droite .

  • La fonction a une expression gardée. Dans ce cas, ⍵≡2⌽⍵c'est le gardien.
  • Si le gardien évalue à 1alors l'expression suivante ≡⍙¨0⍺⍵est exécutée et sa valeur retournée.
  • Si le gardien évalue à 0, cette expression est ignorée et celle qui suit 2 4=...=⍙⍺)est exécutée à la place.

⍵≡2⌽⍵ vérifie si les deux paires d'angles opposés sont égales.

  • 2⌽⍵ fait pivoter le tableau d'angles de 2 positions.
  • ⍵≡vérifie si c'est la même chose que lui-même

≡⍙¨0⍺⍵ renvoie une valeur unique pour chaque forme de type parallélogramme.

  • 0⍺⍵est le tableau à 3 éléments du scalaire 0, le tableau des longueurs latérales et le tableau des angles .
  • ≡⍙¨s'exécute ≡⍙pour chacun de ces éléments.
  • ≡⍙vérifie si toutes les valeurs d'un tableau sont égales en vérifiant si sa rotation de 1 donne le même tableau. Les scalaires ne tournent pas, donc ≡⍙0retourne 1. Comme indiqué ci-dessus, ≡⍙⍺recherche un losange et ≡⍙⍵vérifie un rectangle.

2 4=+/1=2|+⍙↑⍵(=⍙⍺)renvoie une valeur unique pour chaque forme de type non parallélogramme. Ceci est réalisé en entrelaçant les contrôles pour le cerf-volant et le trapèze.


2=+/1=2|+⍙⍵ recherche un trapèze.

  • +⍙⍵donne les sommes des angles adjacents. Les angles intérieurs des lignes parallèles totalisent un angle droit, de même que les angles extérieurs des côtés parallèles d'un quadrilatère. Ainsi, chaque paire de côtés parallèles devrait conduire à deux 1ou -1dans les sommes d'angle adjacentes.

  • 1=2|Cependant, les angles dans sont supérieurs de 1 à ce qu'ils devraient être, donc les angles totalisent réellement à 1ou 3. Cela peut être vérifié par "mod 2 est égal à 1".

  • +/résume le tableau. Cela donne un nombre de sommes d'angle adjacentes qui est 1ou 3.

  • 2= vérifier si cela est égal à 2. (c'est-à-dire s'il y a exactement une paire de côtés parallèles)


4=+/1=2|+⍙(=⍙⍺) vérifie un cerf-volant.

  • (=⍙⍺)donne un tableau indiquant quels côtés adjacents sont égaux. Contrairement à , =travailler par élément. Ainsi, il s'agit d'un tableau à 4 éléments avec 1s où la longueur de ce côté est égale à celle du côté "suivant".

  • +⍙ Somme par paire avec enroulement.

  • 1=2|Puisque (=⍙⍺)donne un tableau booléen (un avec seulement 0s et 1s), les seules valeurs possibles de somme par paire sont 0, 1et 2. C'est la 1=2|même chose que juste 1=.

  • +/résume le tableau. Cela donne un nombre de sommes par paire qui est 1.

  • 4=vérifiez si cela est égal à 4. La seule façon qui se produit est si (=⍙⍺)est 1 0 1 0ou 0 1 0 1. Comme indiqué ci-dessus, cela signifie que la forme est un cerf-volant.


2 4=+/1=2|+⍙↑⍵(=⍙⍺) entrelace les contrôles ci-dessus.

  • ⍵(=⍙⍺)est le tableau imbriqué à 2 éléments du tableau et du tableau(=⍙⍺)

  • promeut le tableau imbriqué en une matrice appropriée. Puisqu'il ⍵(=⍙⍺)s'agit d'un tableau à 2 éléments de tableaux à 4 éléments, le résultat est une matrice 2 × 4.

  • +⍙Étant donné que (et, par extension, ) fait pivoter le dernier axe (horizontal), +⍙une matrice équivaut +⍙à appliquer à chaque ligne individuellement.

  • 1=2|Les deux résidus / mod ( |) et equals ( =) fonctionnent sur une base par élément, même pour les matrices.

  • +/Par défaut, réduire ( /) fonctionne le long du dernier axe (horizontal). Donc, +/additionnez le long des lignes et transformez une matrice 2 × 4 en un tableau simple à 2 éléments.

  • 2 4=Puisque =fonctionne par élément, cela vérifie simultanément les conditions du cerf-volant et du trapèze.


3

Mathematica, 195 octets

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

Avec espace:

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

Sorties 1pour carrés, 2pour losanges, 3pour rectangles, 4pour parallélogrammes, 5pour cerfs-volants, 6pour trapèzes et 7pour tout le reste. Je publierais un lien TIO, mais cela ne fonctionne apparemment pas en mathématiques.

Si les quatre points sont P, Q, Ret S, puis {##,#}est {P,Q,R,S,P}, donc sla liste des vecteurs secondaires {Q-P,R-Q,S-R,P-S}, lest la longueur de ces vecteurs, et rest la condition que l'angle entre Q-Pet R-Qainsi que l'angle entre R-Qet S-Rsont tous deux 90degrés.

Ainsi, si toutes les longueurs des côtés sont égales, le quadrilatère est un losange. Sir c'est le , c'est en fait un carré, sinon c'est juste un losange simple.

Éliminer les losanges, si les deux paires de longueurs de côtés opposés sont égales, alors le quadrilatère est toujours parallélogramme. Si rc'est le cas , c'est en fait un rectangle, sinon, c'est juste un parallélogramme simple.

En excluant les parallélogrammes, la liste des longueurs latérales lest de la forme {a,b,b,a}ou {a,a,b,b}pour certains aet ble quadrilatère est un cerf-volant. Notez qu'il ne peut pas être en plus un trapèze ou ce serait en fait un losange.

Excluant les parallélogrammes et les cerfs-volants, si le quadrilatère a une paire de côtés parallèles, alors c'est un trapèze. Nous vérifions cela en Normalizeing les vecteurs latéraux et en vérifiant si une paire de vecteurs opposés ajoute à{0,0} .

Éliminer tout ce qui précède, si 1 > 0(il vaut mieux), alors le quadrilatère n'est qu'un simple quadrilatère ancien.


1

Python 2 , 463 410 408 397 octets

Enregistré 53 octets en utilisant un tuple dans la sixième ligne au lieu de l'indexation dans une liste.

Enregistrement de 11 octets en passant aux nombres de sortie de 1 à 7 au lieu de la première lettre de chaque forme. Les entiers correspondent comme suit:

  1. Carré
  2. Rectangle
  3. Rhombe
  4. Parallélogramme
  5. Trapèze
  6. Kite
  7. Quadrilatère
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

Essayez-le en ligne!

Non golfé pour montrer la logique

Affiché en tant que fonction, pour afficher la sortie pour les différentes entrées de test. note J'ai changé l'exemple de test "Rectangle" de celui fourni à l'origine dans la question, qui n'était pas un rectangle.

La logique repose sur les produits scalaires et la norme (longueur) des vecteurs formés par les côtés du quadrilatère pour évaluer si les côtés sont égaux en longueur, parallèles sur les côtés opposés ou perpendiculaires aux côtés adjacents.

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

Essayez-le en ligne!


1
Mis à part [(0, 0), (2, 2), (4, 0), (0,-2)]comme cerf
TwiNight

Est-ce que cela fonctionnerait? repl.it/JRzE
Zacharý

@TwiNight Merci. N'a pas vu cette possibilité. Le problème est que mon algorithme initial vérifie uniquement s'il y a UNE paire de côtés de longueur identique. Comme votre exemple le montre, ce n'est pas suffisant. Je devrais vérifier une paire de côtés assortis, puis vérifier si la paire opposée est également de longueur similaire. Trop occupé pour mettre cela en œuvre.
CCB60

0

Lot, 287 octets

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

Sorties en binaire: 1= cerf-volant, 10= quadrilatère, 11= trapèze, 100= parallélogramme, 101= losange, 110= rectangle, 111= carré. Explication: g, h, i, jsont les carrés des longueurs des côtés. pest le nombre de paires de côtés opposés de même longueur, fait la qdistinction entre parallélogrammes / rectangles et rhobmi / carrés en vérifiant si les paires opposées sont en fait égales, fait la rdistinction entre parallélogrammes / losanges et rectangles / carrés via un contrôle de perpendicularité, kvérifie une cerf-volant en recherchant des paires de côtés adjacents égaux et tvérifie la présence d'un trapèze via quelques vérifications latérales parallèles.



@TwiNight Bah, vérifier un cerf-volant est vraiment gênant.
Neil

Oui, j'ai eu la chance de trouver un moyen compact de le faire
TwiNight

@TwiNight je vais vous croire sur parole; APL est complètement illisible pour moi.
Neil

La partie où je vérifie le cerf-volant est 2=|-.=⍙⍺. Semble certainement compact si vous ignorez le travail de calcul (les 4 longueurs de côté) et toute une ligne à définir
TwiNight
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.