Déterminer si un polygone est convexe


21

Écrivez un programme pour déterminer si le polygone d'entrée est convexe . Le polygone est spécifié avec une ligne contenant N , le nombre de sommets, puis N lignes contenant les coordonnées x et y de chaque sommet. Les sommets seront listés dans le sens horaire à partir d'un sommet arbitraire.

Exemple 1

contribution

4
0 0
0 1
1 1
1 0

production

convex

exemple 2

contribution

4
0 0
2 1
1 0
2 -1

production

concave

exemple 3

contribution

8
0 0
0 1
0 2
1 2
2 2
2 1
2 0
1 0

production

convex

x et y sont des entiers, N <1000 et | x |, | y | <1000 . Vous pouvez supposer que le polygone d'entrée est simple (aucune des arêtes ne se croise, seules 2 arêtes touchent chaque sommet). Le programme le plus court gagne.


"Simple" n'inclut pas "les bords consécutifs ne sont pas colinéaires"?! En outre, quelques autres cas de test: (0,0) (0,2) (2,2) (2,0) (1,1); et (1,1) (0,0) (0,2) (2,2) (2,0) - pour tester les cas où la recherche du sommet concave nécessite un habillage de la fin au début.
— Peter Taylor

Cette question vieillit, mais ... Pensez à ajouter un exemple concave avec deux segments alignés, par exemple une modification de l'exemple 2: (0,0), (2,1), (4,2), (1,0) ( 2, -1). Je soulève cela parce que j'ai fudé autour de l'exemple 3 sans m'en rendre compte.
— Jesse Millikan

Réponses:


4

J, 105

echo>('concave';'convex'){~1=#=(o.1)([:>-.~)(o.2)|3([:-/12 o.-@-/@}.,-/@}:)\(,2&{.)j./"1}.0&".;._2(1!:1)3

Réussit les trois tests ci-dessus.

Edit: (111-> 115) Gérez les points colinéaires en éliminant les angles de pi. A gagné quelques personnages ailleurs.

Edit: (115-> 105) Moins stupide.

Explication pour les J-affaiblis:

  • (1!:1)3lire STDIN à EOF. (Je pense.)
  • 0&".;._2 est un bel idiome pour analyser ce type d'entrée.
  • j./"1}. couper la première ligne d'entrée (N 0) et convertir les paires en complexes.
  • (,2&{.) virer les deux premiers points à la fin de la liste.
  • 3(f)\ applique f à une fenêtre coulissante de longueur 3 (3 points pour un angle)
  • [:-/12 o.-@-/@}.,-/@}: est un verbe qui transforme chacun des 3 points en un angle entre -pi et pi.
    • -@-/@}.,-/@}:produit (p1 - p2), (p3 - p2). (Rappelez-vous que ce sont des complexes.)
    • 12 o. donne un angle pour chaque complexe.
    • [:-/(...) donne la différence des deux angles.
  • (o.1)([:>-.~)(o.2)| mod 2 pi, élimine les angles de pi (segments droits) et compare à pi (supérieur à, inférieur à, n'a pas d'importance à moins que les points soient supposés être enroulés dans une direction).
  • 1=#= si tous ces résultats de comparaison 1 ou 0 (avec auto-classification. Cela semble stupide.)
  • echo>('concave';'convex'){~ impression convexe.

3

Python - 149 caractères

p=[map(int,raw_input().split())for i in[0]*input()]*2
print'ccoonncvaevxe'[all((a-c)*(d-f)<=(b-d)*(c-e)for(a,b),(c,d),(e,f)in zip(p,p[1:],p[2:]))::2]

Je pense que vous avez besoin de <=, voir l'exemple 3 que je viens d'ajouter.
— Keith Randall

1
bon sang, cette tranche ...
— st0le

2

Ruby 1,9, 147 133 130 124 123

gets
puts ($<.map{|s|s.split.map &:to_i}*2).each_cons(3).any?{|(a,b),(c,d),(e,f)|(e-c)*(d-b)<(d-f)*(a-c)}?:concave: :convex

1

scala: 297 caractères

object C{class D(val x:Int,val y:Int)
def k(a:D,b:D,c:D)=(b.y-a.y)*(c.x-b.x)>=(c.y-b.y)*(b.x-a.x) 
def main(a:Array[String]){val s=new java.util.Scanner(System.in)
def n=s.nextInt
val d=for(x<-1 to n)yield{new D(n,n)}print((true/:(d:+d.head).sliding(3,1).toList)((b,t)=>b&&k(t(0),t(1),t(2))))}}

1
Vous pouvez raser trois caractères en utilisant def main(a:...au lieu de def main(args:....
— Gareth

Oui, je me suis remarqué, mais 299 à 149 ne m'amène pas dans le domaine de quelqu'un d'autre. Peut-être que si je trouve d'autres améliorations - ah, il y en a une: n est un nom de fonction (suivant) et un nom de variable.
— utilisateur inconnu
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.