Tentukan apakah poligon adalah cembung


21

Tulis program untuk menentukan apakah poligon input cembung . Poligon ditentukan dengan satu garis yang berisi N , jumlah simpul, kemudian garis N yang berisi koordinat x dan y dari setiap simpul. Verteks akan terdaftar searah jarum jam mulai dari titik sembarang.

Contoh 1

memasukkan

4
0 0
0 1
1 1
1 0

keluaran

convex

contoh 2

memasukkan

4
0 0
2 1
1 0
2 -1

keluaran

concave

contoh 3

memasukkan

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

keluaran

convex

x dan y adalah bilangan bulat, N <1000 , dan | x |, | y | <1000 . Anda dapat mengasumsikan bahwa poligon input sederhana (tidak ada sisi yang bersilangan, hanya 2 sisi yang menyentuh setiap titik). Kemenangan program terpendek.


"Sederhana" tidak termasuk "tepi berturut-turut adalah non-collinear" ?! Juga, beberapa lagi kasus uji: (0,0) (0,2) (2,2) (2,0) (1,1); dan (1,1) (0,0) (0,2) (2,2) (2,0) - untuk menguji kasus-kasus di mana menemukan simpul cekung membutuhkan pembungkus dari ujung kembali ke awal.
Peter Taylor

Pertanyaan ini menua, tetapi ... Pertimbangkan untuk menambahkan contoh cekung dengan dua segmen yang disejajarkan, misalnya modifikasi contoh 2: (0,0), (2,1), (4,2), (1,0) ( 2, -1). Saya membawa ini karena saya mencari-cari contoh 3 tanpa menyadarinya.
Jesse Millikan

Jawaban:


4

J, 105

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

Lewati ketiga tes di atas.

Sunting: (111-> 115) Tangani titik co-linear dengan menghilangkan sudut pi. Memperoleh beberapa karakter di tempat lain.

Sunting: (115-> 105) Kurang bodoh.

Penjelasan untuk Tunanetra:

  • (1!:1)3baca STDIN ke EOF. (Kupikir.)
  • 0&".;._2 adalah ungkapan yang bagus untuk menguraikan input seperti ini.
  • j./"1}. memotong jalur input pertama (N 0) dan mengubah pasangan menjadi kompleks.
  • (,2&{.) tempelkan dua poin pertama ke akhir daftar.
  • 3(f)\ berlaku untuk jendela geser dengan panjang 3 (3 titik untuk sudut)
  • [:-/12 o.-@-/@}.,-/@}: adalah kata kerja yang mengubah masing-masing 3 titik menjadi sudut antara -pi dan pi.
    • -@-/@}.,-/@}:menghasilkan (p1 - p2), (p3 - p2). (Ingatlah bahwa ini adalah kompleks.)
    • 12 o. memberikan sudut untuk setiap kompleks.
    • [:-/(...) memberikan perbedaan dari dua sudut.
  • (o.1)([:>-.~)(o.2)| mod 2 pi, hilangkan sudut pi (segmen lurus), dan bandingkan dengan pi (lebih besar dari, kurang dari, tidak masalah kecuali titik-titiknya seharusnya luka dalam satu arah).
  • 1=#= jika semua hasil perbandingan 1 atau 0 (Dengan mengklasifikasikan sendiri. Ini tampak bodoh.)
  • echo>('concave';'convex'){~ cetak cembung.

3

Python - 149 karakter

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]

Saya pikir Anda perlu <=, lihat contoh 3 saya baru saja menambahkan.
Keith Randall

1
Sialan, irisan itu ...
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 karakter

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
Anda dapat mencukur tiga karakter dengan menggunakan def main(a:...sebagai gantinya def main(args:....
Gareth

Ya, saya memperhatikan diri saya sendiri, tetapi 299 hingga 149 tidak membawa saya ke area orang lain. Mungkin jika saya menemukan perbaikan lain - ah, ada satu: n adalah nama fungsi (berikutnya) dan nama variabel.
pengguna tidak diketahui
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.