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.

Keith Randall
la source
"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.
Jesse Millikan
la source
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]
grignoteur
la source
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
Lowjacker
la source
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))))}}
Utilisateur inconnu
la source
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