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.