Tujuan Anda adalah untuk menentukan apakah titik 2D X yang diberikan terletak di dalam area segitiga dengan simpul A, B, C yang diberikan.
Tulis fungsi yang mengambil dalam koordinat titik uji X dan tiga simpul segitiga (jadi total koordinat 8) dan mengembalikan True jika titik terletak di dalam segitiga itu, dan Salah jika terletak di luar.
Jangan khawatir tentang tepi kasus. Jika titik terletak pada batas segitiga (tepi atau dhuwur) atau segitiga sebenarnya merupakan segmen garis, kode Anda dapat melakukan apa saja, termasuk menabrak. Juga jangan khawatir tentang stabilitas numerik atau presisi floating-point.
Kode Anda harus berupa fungsi bernama. Cuplikan kode tidak akan diterima.
Karakter yang paling sedikit menang.
Memasukkan:
Delapan bilangan real mewakili koordinat. Angka-angka akan berada dalam kisaran (-1,1)
.
Format input yang tepat fleksibel. Anda dapat, misalnya, mengambil dalam delapan angka, daftar delapan angka, daftar empat poin yang masing-masing diberikan oleh sebuah tuple, sebuah matriks 2 * 4, empat angka kompleks, dua daftar koordinat x dan koordinat y, dan seterusnya.
Masukan harus berupa angka-angka dalam wadah, tanpa data tambahan. Anda tidak dapat menggunakan input untuk melakukan preprocessing apa pun, Anda juga mungkin tidak memerlukan kendala pada input, seperti mengharuskan poin diberikan dalam koordinat naik y. Input Anda harus mengizinkan delapan koordinat (meskipun kode Anda dapat berperilaku sewenang-wenang dalam kasus tepi yang disebutkan sebelumnya).
Harap sebutkan format input Anda.
Keluaran:
Baik Boolean yang sesuai True
/ False
, nomor yang sesuai 1
/ 0
, atau analog dalam bahasa Anda.
Uji kasus
Input diberi daftar [X,A,B,C]
empat tupel, titik uji pertama, lalu tiga simpul segitiga. Saya telah mengelompokkan mereka ke dalam output yang seharusnya True
dan yang seharusnya False
.
True
contoh:
[(-0.31961, -0.12646), (0.38478, 0.37419), (-0.30613, -0.59754), (-0.85548, 0.6633)]
[(-0.87427, -0.00831), (0.78829, 0.60409), (-0.90904, -0.13856), (-0.80685, 0.48468)]
[(0.28997, -0.03668), (-0.28362, 0.42831), (0.39332, -0.07474), (-0.48694, -0.10497)]
[(-0.07783, 0.04415), (-0.34355, -0.07161), (0.59105, -0.93145), (0.29402, 0.90334)]
[(0.36107, 0.05389), (0.27103, 0.47754), (-0.00341, -0.79472), (0.82549, -0.29028)]
[(-0.01655, -0.20437), (-0.36194, -0.90281), (-0.26515, -0.4172), (0.36181, 0.51683)]
[(-0.12198, -0.45897), (-0.35128, -0.85405), (0.84566, 0.99364), (0.13767, 0.78618)]
[(-0.03847, -0.81531), (-0.18704, -0.33282), (-0.95717, -0.6337), (0.10976, -0.88374)]
[(0.07904, -0.06245), (0.95181, -0.84223), (-0.75583, -0.34406), (0.16785, 0.87519)]
[(-0.33485, 0.53875), (-0.25173, 0.51317), (-0.62441, -0.90698), (-0.47925, 0.74832)]
False
contoh:
[(-0.99103, 0.43842), (0.78128, -0.10985), (-0.84714, -0.20558), (-0.08925, -0.78608)]
[(0.15087, -0.56212), (-0.87374, -0.3787), (0.86403, 0.60374), (0.01392, 0.84362)]
[(0.1114, 0.66496), (-0.92633, 0.27408), (0.92439, 0.43692), (0.8298, -0.29647)]
[(0.87786, -0.8594), (-0.42283, -0.97999), (0.58659, -0.327), (-0.22656, 0.80896)]
[(0.43525, -0.8923), (0.86119, 0.78278), (-0.01348, 0.98093), (-0.56244, -0.75129)]
[(-0.73365, 0.28332), (0.63263, 0.17177), (-0.38398, -0.43497), (-0.31123, 0.73168)]
[(-0.57694, -0.87713), (-0.93622, 0.89397), (0.93117, 0.40775), (0.2323, -0.30718)]
[(0.91059, 0.75966), (0.60118, 0.73186), (0.32178, 0.88296), (-0.90087, -0.26367)]
[(0.3463, -0.89397), (0.99108, 0.13557), (0.50122, -0.8724), (0.43385, 0.00167)]
[(0.88121, 0.36469), (-0.29829, 0.21429), (0.31395, 0.2734), (0.43267, -0.78192)]
Jawaban:
Javascript / ECMAScript 6,
161159158/152Javascript:
Versi ECMAScript 6 (terima kasih m.buettner, hemat 6 karakter)
Sebut saja (mengembalikan
true
ataufalse
):Menggunakan beberapa matematika koordinat barycentric yang mewah berdasarkan kode dari jawaban ini . Versi ungolfed untuk kesenangan membaca Anda mengikuti:
sumber
(a*(l-n)+i*(g-e)+n*e-g*l)
alih-alih(-g*l+a*(-n+l)+i*(g-e)+n*e)
?Python 2.7
1281271171101091039995949190Usaha kode-golf pertama saya!
Kode
Dibawa sebagai input (x, y, t) di mana (x, y) adalah titik yang kami periksa dan t adalah segitiga t = ((x1, y1), (x2, y2), (x3, y3)).
Penjelasan
Saya menghitung faktor penentu dari matriks
Penentu ini mewakili jarak yang ditandatangani dari sisi segitiga ke titik (x, y). Jika mereka semua memiliki tanda yang sama, maka titiknya berada di sisi yang sama dari setiap garis dan dengan demikian terkandung dalam segitiga.
Dalam kode di atas,
a*y+c*b+d*x-d*a-c*y-b*x
merupakan penentu salah satu dari matriks ini.Saya menggunakan fakta itu
True+True+True==3
danFalse+False+False==0
untuk menentukan apakah semua penentu ini memiliki tanda yang sama.Saya menggunakan indeks daftar negatif Python dengan menggunakan
t[-1]
alih-aliht[(i+1)%3]
.Terima kasih Peter atas ide untuk digunakan
s%3<1
daripadas in(0,3)
memeriksa apakah s adalah 0 atau 3!Versi Sagemath
Tidak benar-benar solusi yang berbeda jadi saya memasukkannya dalam jawaban ini, solusi sagemath menggunakan 80 karakter:
dimana
p=[x,y]
, dant=[[x1,y1],[x2,y2],[x3,y3]]
sumber
s in (0,3)
disingkat menjadis%3<1
?-1,0,1 ... t[i]+t[i+1]
setara dengan0,1,2 ... t[i-1]+t[i]
in -1,0,1
sebelum membaca ini. Sebenarnya cara Anda lebih mudah dibaca jadi saya tetap akan menggunakannya.sum
jika Anda menyelimuti0,1,2
dalam kurung, hal karakter dengan mengganti spasi. Alasannya adalah bahwa Python memungkinkan pemahaman unbracketed untuk diteruskan ke fungsi, tetapi koma dalam tuple telanjang1,2,3
membingungkannya karena mencoba mengurai mereka sebagai argumen terpisah.Mathematica, 67 byte
Fungsi ini mengambil dua argumen, titik
X
dan daftar titik{A,B,C}
, yang disebut masing#
-#2
masing. Itu jika Anda meneleponmaka Anda akan mendapatkan
#
sebagaiX
dan#2
sebagai{A,B,C}
. (Perhatikan bahwa ada dua fungsi anonim lainnya yang bersarang di dalam kode -#
dan#2
memiliki arti berbeda di dalamnya.)Berikut ini penjelasan fungsi itu sendiri:
Perhatikan bahwa fungsi ini akan benar-benar bekerja untuk setiap cembung n-gon selama simpul diberikan baik searah jarum jam atau berlawanan arah jarum jam order.
sumber
Det
?CJam,
66635952463432313028 karakterSetelah mengubah string Unicode, kode berikut ( 33 byte ) akan dievaluasi:
Diharapkan
X [A B C]
sebagai input, di mana setiap titik dalam formulir[double double]
. Outputnya 1 atau 0.Cobalah online.
Terima kasih banyak kepada user23013 untuk menyimpan 6 karakter (13 byte kode terkompresi)!
Uji kasus
sumber
{
dan}
dan diperlakukan sebagai satu kesatuan. Mirip dengan blok kode dalam C / java, kecuali blok adalah objek kelas satu dan dapat ditugaskan ke variabel (dengan demikian mendefinisikan fungsi).1m<@m*
menyiapkan 3 pasang X dani+1
simpul ( th) segitiga berikutnya.@-@@-
memindahkan titik (i
th) saat ini ke titik asal (dan mencerminkan jika tidak@-\@-
, tetapi tidak masalah).@@*@@*>
menghitung sumbu z dari produk silang, alias determinan, dan mengembalikan1
jika negatif.:+3%!
mengembalikan apakah mereka semua sama, yaitu, ketiga adalah negatif atau non-negatif, yang berarti positif kecuali untuk kasus tepi. Saya pikir lebih sulit membaca CJam daripada bermain golf.{[_1m<\]z\f{f{+~@-@@-}~@@*@@*>})-!}:T
. Gunakan2m>
atauWm<
untuk keamanan Unicode.{2*2/\f{f{+~@-@@-}~@@*@@*>})-!}:T
C - 156 byte
Input adalah larik 3 float di X, 3 float di Y dan pisahkan x dan y untuk titik uji. Bonus: menangani semua kasus tepi!
Diadaptasi dari PNPOLY.
sumber
i;j;c;f(float*X,float*Y,float x,float y){for(c=i=0,j=2;i<3;)c^=(Y[i]>y)-(Y[j]>y)&(x<(X[j]-X[i])*(y-Y[i])/(Y[j]-Y[i])+X[j=i++]);return c;}
137 - diuji dalam javascriptPyth 1.0.5 ,
575451Menentukan fungsi g, yang mengambil dua input: titik uji, dan kemudian daftar simpul segitiga. Output
True
danFalse
. Catatan: Hancurkan input, khususnya b, daftar simpul segitiga.Coba di sini . Beberapa karakter terakhir,
gvwvw
panggil fungsi dengan case uji pada dua baris berikutnya.Berdasarkan algoritma ini
Penjelasan:
Perang CJam - Pyth mengamuk terus!
sumber
w
mengambil input STDIN?Z
dengan set kosong yang Anda kumpulkanZ|=
, lalu menguji panjangnya untuk melihat apakah hanya0
atau1
hanya terlihat? Strateginya ternyata lebih lama dalam Python, tapi mungkin itu layak menggunakan primitif Pyth.J
6445 (42 tanpa tugas)Penugasan tidak diperlukan untuk hal yang akan berfungsi, jadi tidak yakin apakah akan menghitungnya atau tidak. Mengambil keuntungan dari input fleksibel: Saya ingin memiliki array (1 + jumlah simpul) x (dimensi ruang).
Berharap untuk mencetak beberapa poin tambahan di sini ...: Benda ini berfungsi untuk semua dimensi simpleks, tidak hanya segitiga dalam pesawat, tetapi juga piramida 3 sisi dalam ruang 3d dan sebagainya. Ia juga bekerja ketika jumlah simpul simpleks lebih kecil dari (n +1), maka ia menghitung apakah proyeksi titik ke simpleks berada di dalam atau tidak.
Itu mengkonversi ke koordinat barycentric , kemudian memeriksa yang negatif, menunjukkan titik di luar. Apakah pikiran J menggunakan _ untuk negatif
Jalankan pada contoh yang diberikan:
sumber
N+1
simpul maksimum . Misalnya 4 vertex pyramid dalam ruang 3-D, atau 5 vertex simplex dalam ruang 4-D. Jumlah simpul bisa lebih rendah daripadaN+1
, dalam hal ini algoritma melihat apakah proyeksi ortogonal ke hyperplane tempat simpleks berada di dalam simpleks atau tidak (misalnya simpleks 2 titik dalam 2-D akan diproyeksikan pada garis dan diperiksa) apakah proyeksi ini terletak di antara titik akhir)HTML5 + JS, 13b + 146b / 141b / 114 karakter
HTML:
JS (146b):
atau ES6 (141b):
atau ES6 unicode-obfuscated (114 chars):
demo: http://jsfiddle.net/xH8mV/
Kebingungan Unicode dibuat dengan: http://xem.github.io/obfuscatweet/
sumber
Python (65)
Orang-orang sepertinya sudah selesai mengirimkan, jadi saya akan mengirimkan solusi saya sendiri untuk pertanyaan saya.
X
adalah bilangan kompleks yang mewakili titik uji, danL
merupakan daftar tiga titik, masing-masing bilangan kompleks.Pertama, saya akan menjelaskan versi kode yang kurang golf;
Kami menggeser titik-titik
A,B,C,X
sehinggaX
berada pada titik asal, mengambil keuntungan dari aritmatika kompleks built-in Python. Kita perlu memeriksa apakah sumbernya terkandung dalam lambung cembungA,B,C
. Ini setara dengan titik asal yang selalu terletak di sisi yang sama (kiri atau kanan) dari segmen garis AB, BC, dan AC.Segmen
AB
memiliki asal di sebelah kiri jika satu perjalanan berlawanan arah jarum jam kurang dari 180 derajat untuk mendapatkan dari A ke B, dan di sebelah kanan sebaliknya. Jika kita mempertimbangkan suduta
,,b
danc
sesuai dengan titik-titik ini, ini berartib-a < 180 degrees
(sudut diambil dalam kisaran 0 hingga 360 derajat). Sebagai bilangan kompleksangle(B/A)=angle(B)/angle(A)
,. Juga,angle(x) < 180 degrees
tepatnya untuk titik di atas setengah pesawat, yang kami periksa viaimag(x)>0
.Jadi apakah asal terletak di sebelah kiri AB dinyatakan sebagai
(A/B).imag>0
. Memeriksa apakah ini semua sama untuk setiap pasangan siklik diA,B,C
memberitahu kita apakah segitigaABC
mengandung asal.Sekarang, mari kita kembali ke kode golf sepenuhnya
Kami menghasilkan setiap pasangan siklik
(A-X,B-X,C-X)=(L[0]-X,L[1]-X,L[2]-X)
, mengambil keuntungan dari indeks daftar Python negatif yang membungkus (L[-1]
=L[2]
). Untuk memeriksa apakah Bools adalah semuaTrue
(1
) atau semuaFalse
(0
), kami menambahkannya dan memeriksa pembagian dengan 3, seperti yang dilakukan banyak solusi.sumber
Fortran -
232218195174Sangat mengerikan. Fungsi ini mengerikan karena persyaratan bahwa data dilewatkan ke sana dan kami tidak dapat memprosesnya.
Penurunan 14 karakter adalah karena saya lupa golf nama fungsi dari tes saya berjalan. Penurunan lebih lanjut disebabkan oleh pengetikan tersirat dan lupa untuk mengubah nama fungsi. 20 karakter berikutnya keluar karena membaca dalam poin sebagai array tunggal. Program lengkapnya adalah
sumber
logical function T(x);real x(8);p=x(1)-x(3);q=x(2)-x(4);r=x(5)-x(3);s=x(6)-x(4);u=x(7)-x(3);v=x(8)-x(4);o=r*v-u*s;T=ALL([p*(s-v)+q*(u-r)+o,p*v-q*u,q*r-p*s]>=o);end
Saya sudah mencoba memperpendek ini lebih lanjut dengan menggunakan operasi daftar, tapi sayangnya itu tidak berhasil dengan baik.logical function T(x);real x(8);p=x(1)-x(3);q=x(2)-x(4);r=x(5)-x(3);s=x(6)-x(4);u=x(7)-x(3);v=x(8)-x(4);a=r*v-u*s;b=p*v-q*u;d=q*r-p*s;T=ALL([a-b-d,b,d]>=a);end
Saya harap saya tidak membuat kesalahan dalam transformasi! Meskipun sepertinya kode asli Anda tidak lulus semua testcases.True
dalam OP memberikanFalse
jika saya menukarB
danC
nilai sambil memberikanTrue
untuk orientasi asli.a < 0
, yang secara efektif membalikkan kondisi yang harus Anda uji. Sayangnya ini tidak bisa diperbaiki dengan membungkus segala sesuatu dalamabs
, karena kemudian kondisi tersiratb
dand
memiliki tanda yang sama sepertia
hilang. Ini dapat diperbaiki dengan menggunakan sesuatu seperti (sekali lagi, menggunakan kembali notasi dan variabel yang telah ditentukan dari komentar terakhir saya)e=a-b-d;T=ALL([a*a-b*b,a*a-d*d,a*a-e*e,a*b,a*d,a*e]>=0)
- yang mungkin dapat di-golf lebih.MATLAB: 9!
Tidak banyak dari saya untuk menulis di sini
Dapat disebut seperti ini:
Output ditugaskan ke variabel bernama
ans
Jika saya benar-benar harus menulis suatu fungsi, mungkin sesuatu seperti itu, mungkin dapat dioptimalkan:
sumber
f=@(a,b,c,d)inpolygon(a,b,c,d)
C # 218 (149?)
Mungkin tidak seefisien karakter sebagai metode matematika, tapi itu menyenangkan menggunakan perpustakaan. Kebetulan juga agak lambat.
Juga memanfaatkan "Juga jangan khawatir tentang stabilitas numerik atau presisi floating-point." - Sayangnya,
GraphicsPath
menggunakanint
s secara internal, sehingga nilai dalam rentang -1 <f <1 hanya dapat memiliki tiga nilai yang mungkin. Karena float hanya memiliki 7 digit presisi, saya hanya mengalikan 1e7 untuk mengubahnya menjadi bilangan bulat. Hm, saya kira itu tidak benar-benar kehilangan presisi. Ini juga dapat dieksploitasi dengan cara lain: Saya mungkin bisa mengambil keuntungan dari mengabaikan presisi dan hanya memberikan jawaban yang "salah".Jika saya boleh mengabaikan biaya karakter untuk mengimpor perpustakaan, 149 (paling tidak,
System.Linq
danSystem.Drawing
cukup standar pada sebagian besar proyek WinForms, tetapiSystem.Drawing.Drawing2D
mungkin sedikit sulit):Program uji (ya, jelek):
sumber
Haskell -
233127Menggunakan produk silang seperti dijelaskan di sini :
Solusi sebelumnya diimplementasikan menggunakan koordinat barycentric dan formula yang dijelaskan dalam jawaban Stack Exchange ini :
Keduanya berfungsi
g
danh
mengambil empat pasang, yang pertama adalah titik yang akan diuji untuk dimasukkan dan sisanya adalah koordinat dari simpul segitiga.Untuk menguji dengan input sampel:
Solusi yang tidak digabungkan:
sumber
JavaScript (ES6) 120
Langsung disalin dari jawaban saya ke pertanyaan lain ini
Uji di konsol FireFox / FireBug
Keluarkan semua 1s
Keluarkan semua 0s
sumber
SmileBASIC,
111100 karakterGambarlah segitiga dan periksa warna piksel pada titik tersebut. Segitiga ditingkatkan menjadi 99999x dan digeser sehingga titik untuk memeriksa akan berada pada (0,0) sebelum ditarik, untuk meminimalkan kehilangan presisi.
sumber
Perakitan FPU Intel 8087,
222220 byteHanya menggunakan perangkat keras FPU 8087 untuk menghitung. Berikut ini adalah versi yang belum dirakit (yang tidak diunggulkan dalam kasus ini) sebagai MACRO (akan memberi Anda 220 kode byte heksa):
Penjelasan
Menggunakan determinasi untuk menghitung luas segitiga ABC, dan kemudian segitiga terbentuk dengan titik X dan dua titik lainnya dari segitiga ABC. Jika luas segitiga ABC sama dengan jumlah luas segitiga XBC + AXC + ABX, maka titik tersebut berada dalam segitiga. Hasilnya dikembalikan sebagai ZF.
Apa yang rapi tentang ini
Semua operasi matematika dan floating point dilakukan dalam perangkat keras dengan presisi diperpanjang 80-bit. Perbandingan floating point akhir juga dilakukan dalam perangkat keras sehingga akan sangat akurat.
Ini juga menggunakan delapan register tumpukan 8087 sekaligus.
Apa yang tidak begitu rapi tentang ini
Karena titik-titik segitiga harus dicolokkan kembali ke formula beberapa kali selama perhitungan, itu mengharuskan setiap variabel dalam memori dimuat ke register tumpukan FPU satu per satu dalam urutan yang benar. Meskipun ini dapat dengan mudah dimodelkan seperti fungsi sebagai MACRO, itu berarti bahwa kode diperluas setiap kali pada perakitan, membuat kode yang berlebihan. 41 byte disimpan dengan memindahkan beberapa segmen kode berulang yang sama ke dalam PROCs. Namun itu membuat kode kurang dapat dibaca, sehingga daftar di atas adalah tanpanya (itulah sebabnya itu diberi label "ungolfed").
Tes
Berikut ini adalah program pengujian menggunakan IBM DOS yang menampilkan keluaran:
Keluaran
sumber
C 414 (dulu 465)
Golf
Deklarasi fungsi asli ditambahkan untuk penjelasan
Ditulis ulang sebagai fungsi bernama: input melalui stdin satu baris atau semua dalam satu baris yang dipisahkan ruang.
sumber
double
mendefinisikan ulangD
tetapi Anda masih menggunakandouble
dalam kode.Jawa, 149 karakter
Mengerikan mengingat saya harus menulis "Matematika." setiap saat. Ini adalah program aktual:
di mana a adalah x dari titik a, b adalah x dari titik b, c untuk x dari c, d adalah y dari a, e adalah y dari b, f adalah y dari c, dan x dan y adalah x dan y pokoknya. Boolean k menentukan apakah itu benar atau tidak.
sumber
100*
?JavaScript 125/198
Jika poin disediakan dalam 8 argumen:
Jika poin disediakan dalam array 2 dimensi:
Kode ini tidak menggunakan matematika vektor mewah mana pun. Sebagai gantinya, itu hanya menggunakan trik aljabar sederhana untuk menentukan apakah titik itu di dalam segitiga atau tidak. Rumus:
yang memberitahu titik adalah di sisi mana dari sebuah garis , berasal dari menyusun ulang definisi kemiringan:
Jika kita menguji semua 3 sisi, ketiga harus menghasilkan beberapa angka dengan tanda yang sama hanya ketika titik berada di dalam segitiga karena kita mengujinya di sekitar segitiga. Jika titik berada di samping maka salah satu tes harus mengembalikan 0.
kode uji jsFiddle: http://jsfiddle.net/DerekL/zEzZU/
97 karakter (tidak termasuk spasi atau tab) dihitung jika dikonversi ke CoffeeScript:
115 karakter jika diubah menjadi ES6:
sumber
d=(x,y,...)=>{...}
. Dalam kasus Anda, Anda dapat menyimpan lebih banyak lagi dengan menggunakan CoffeeScript, yang tidak perlureturn
: pastebin.com/RVFk1D5k ... dan dalam hal apa pun Anda dapat menyimpan satu byte dengan menggunakan<1
alih-alih==0
.R, 23
Terinspirasi oleh MATLAB ,
disebut seperti di
SDMTools::pnt.in.poly(point,triangle)
manapoint
vektor panjang-2 dantriangle
matriks 3x2 dari simpul. SDMTools tersedia di CRAN.sumber
Mathematica, 38 karakter
Contoh:
(* Benar *)
sumber
C (gcc) , 108 byte
Cobalah online!
Membawa tiga produk silang dan kembali
1
jika tandak̂
komponen tidak berubah.sumber