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.