Bestimmen Sie, ob ein Polygon konvex ist


21

Schreiben Sie ein Programm, um festzustellen, ob das Eingabepolygon konvex ist . Das Polygon wird mit einer Linie angegeben, die N enthält , die Anzahl der Scheitelpunkte, und dann mit N Linien, die die x- und y- Koordinaten jedes Scheitelpunkts enthalten. Die Scheitelpunkte werden ab einem beliebigen Scheitelpunkt im Uhrzeigersinn aufgelistet.

Beispiel 1

Eingang

4
0 0
0 1
1 1
1 0

Ausgabe

convex

Beispiel 2

Eingang

4
0 0
2 1
1 0
2 -1

Ausgabe

concave

Beispiel 3

Eingang

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

Ausgabe

convex

x und y sind ganze Zahlen, N <1000 und | x |, | y | <1000 . Sie können davon ausgehen, dass das Eingabepolygon einfach ist (keine der Kanten kreuzt sich, nur 2 Kanten berühren jeden Scheitelpunkt). Kürzeste Sendung gewinnt.


"Einfach" beinhaltet nicht "aufeinanderfolgende Kanten sind nicht kollinear" ?! Außerdem einige weitere Testfälle: (0,0) (0,2) (2,2) (2,0) (1,1); und (1,1) (0,0) (0,2) (2,2) (2,0) - um die Fälle zu testen, in denen das Finden des konkaven Scheitelpunkts ein Umwickeln vom Ende zurück zum Anfang erfordert.
— Peter Taylor

Diese Frage altert, aber ... Fügen Sie ein konkaves Beispiel mit zwei ausgerichteten Segmenten hinzu, z. B. eine Modifikation von Beispiel 2: (0,0), (2,1), (4,2), (1,0) ( 2, -1). Ich erwähne dies, weil ich Beispiel 3 durchgespielt habe, ohne es zu merken.
— Jesse Millikan

Antworten:


4

J, 105

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

Besteht alle drei oben genannten Tests.

Bearbeiten: (111-> 115) Behandeln Sie kolineare Punkte, indem Sie die Pi-Winkel eliminieren. Ich habe ein paar Charaktere woanders bekommen.

Bearbeiten: (115-> 105) Weniger dumm.

Erklärung für die J-beeinträchtigten:

  • (1!:1)3Lesen Sie STDIN zu EOF. (Ich glaube.)
  • 0&".;._2 ist eine nette Redewendung für das Parsen dieser Art von Eingaben.
  • j./"1}. Hüpfe aus der ersten Eingabezeile (N 0) und wandle Paare in Komplexe um.
  • (,2&{.) Heften Sie die ersten beiden Punkte an das Ende der Liste.
  • 3(f)\ gilt f für Schiebefenster der Länge 3 (3 Punkte für einen Winkel)
  • [:-/12 o.-@-/@}.,-/@}: ist ein Verb, das jeweils 3 Punkte in einen Winkel zwischen -pi und pi umwandelt.
    • -@-/@}.,-/@}:erzeugt (p1 - p2), (p3 - p2). (Denken Sie daran, dass dies Komplexe sind.)
    • 12 o. gibt einen Winkel für jeden Komplex an.
    • [:-/(...) gibt die Differenz der beiden Winkel an.
  • (o.1)([:>-.~)(o.2)| mod 2 pi, eliminiere die Winkel von pi (gerade Segmente) und vergleiche mit pi (größer als, kleiner als, spielt keine Rolle, wenn die Punkte nicht in eine Richtung gewickelt werden sollen).
  • 1=#= Wenn alle diese Vergleiche zu 1 oder 0 führen (Mit Selbsteinstufung. Dies scheint dumm.)
  • echo>('concave';'convex'){~ Drucken Sie konvex.

3

Python - 149 Zeichen

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]

Ich denke, Sie brauchen <=, siehe Beispiel 3, das ich gerade hinzugefügt habe.
— Keith Randall

1
Verdammt, das Stück ...
— 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 Zeichen

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
Sie können sich von drei Zeichen rasieren, indem Sie def main(a:...anstelle von verwenden def main(args:....
— Gareth

Ja, ich habe es selbst bemerkt, aber 299 bis 149 bringen mich nicht in die Nähe von jemand anderem. Vielleicht, wenn ich andere Verbesserungen finde - ah, es gibt eine: n ist ein Funktionsname (next) und ein Variablenname.
— Benutzer unbekannt
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.