Determina se un poligono è convesso


21

Scrivi un programma per determinare se il poligono di input è convesso . Il poligono viene specificato con una riga contenente N , il numero di vertici, allora N righe contenenti il x ed y coordinate di ogni vertice. I vertici verranno elencati in senso orario a partire da un vertice arbitrario.

Esempio 1

ingresso

4
0 0
0 1
1 1
1 0

produzione

convex

esempio 2

ingresso

4
0 0
2 1
1 0
2 -1

produzione

concave

esempio 3

ingresso

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

produzione

convex

x ed y sono numeri interi, n <1000 , e | x |, | y | <1000 . Si può presumere che il poligono di input sia semplice (nessuno dei bordi si incrocia, solo 2 bordi toccano ciascun vertice). Vince il programma più breve.


"Semplice" non include "i bordi consecutivi sono non collineari" ?! Inoltre, un altro paio di casi di test: (0,0) (0,2) (2,2) (2,0) (1,1); e (1,1) (0,0) (0,2) (2,2) (2,0) - per testare i casi in cui la ricerca del vertice concavo richiede l'avvolgimento dalla fine fino all'inizio.
Peter Taylor,

Questa domanda sta invecchiando, ma ... Considera di aggiungere un esempio concavo con due segmenti allineati, ad esempio una modifica dell'esempio 2: (0,0), (2,1), (4,2), (1,0) ( 2, -1). Ne ho parlato perché ho sfogliato l'esempio 3 senza accorgermene.
Jesse Millikan,

Risposte:


4

J, 105

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

Supera tutte e tre le prove sopra.

Modifica: (111-> 115) Gestisci punti co-lineari eliminando gli angoli di pi. Hai ottenuto qualche personaggio altrove.

Modifica: (115-> 105) Meno stupido.

Spiegazione per i non vedenti:

  • (1!:1)3leggi STDIN su EOF. (Penso.)
  • 0&".;._2 è un bel linguaggio per analizzare questo tipo di input.
  • j./"1}. tagliare la prima riga di input (N 0) e convertire le coppie in complessi.
  • (,2&{.) virare i primi due punti alla fine della lista.
  • 3(f)\ applica f alla finestra scorrevole di lunghezza 3 (3 punti per un angolo)
  • [:-/12 o.-@-/@}.,-/@}: è un verbo che trasforma ogni 3 punti in un angolo tra -pi e pi.
    • -@-/@}.,-/@}:produce (p1 - p2), (p3 - p2). (Ricorda che si tratta di complessi.)
    • 12 o. dà un angolo per ogni complesso.
    • [:-/(...) dà la differenza dei due angoli.
  • (o.1)([:>-.~)(o.2)| mod 2 pi, elimina gli angoli di pi (segmenti diritti) e confronta con pi (maggiore di, minore di, non importa a meno che i punti non debbano essere avvolti in una direzione).
  • 1=#= se tutti questi confronti risultano 1 o 0 (Con autoclassificazione. Questo sembra stupido.)
  • echo>('concave';'convex'){~ stampa convessa.

3

Python - 149 caratteri

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]

Penso che tu abbia bisogno di <=, vedi esempio 3 che ho appena aggiunto.
Keith Randall,

1
dannazione, quella fetta ...
via

2

Rubino 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 caratteri

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
Puoi radere di tre caratteri usando def main(a:...invece di def main(args:....
Gareth,

Sì, mi sono notato, ma da 299 a 149 non mi porta nell'area di qualcun altro. Forse se trovo altri miglioramenti - ah, ce n'è uno: n è un nome di funzione (successivo) e un nome di variabile.
utente sconosciuto
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.