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.