Tantangan ini didasarkan pada deteksi tabrakan aktual yang harus saya tulis untuk permainan sederhana baru-baru ini.
Tulis program atau fungsi yang, mengingat dua objek, mengembalikan nilai yang benar atau salah tergantung pada apakah kedua objek tersebut bertabrakan (mis. Berpotongan) atau tidak.
Anda perlu mendukung tiga jenis objek:
- Segmen garis : diwakili oleh 4 pelampung, menunjukkan dua titik akhir, yaitu (x 1 , y 1 ) dan (x 2 , y 2 ) . Anda dapat mengasumsikan bahwa titik akhir tidak identik (sehingga segmen garis tidak mengalami degenerasi).
- Cakram : yaitu lingkaran yang diisi, diwakili oleh 3 pelampung, dua untuk pusat (x, y) dan satu (positif) untuk jari-jari r .
- Rongga : ini adalah pelengkap disk. Artinya, rongga mengisi semua ruang 2D, kecuali wilayah melingkar, ditentukan oleh pusat dan jari-jari.
Program atau fungsi Anda akan menerima dua objek tersebut dalam bentuk integer pengidentifikasi (pilihan Anda) dan 3 atau 4 floatnya. Anda dapat mengambil input melalui STDIN, ARGV atau argumen fungsi. Anda dapat mewakili input dalam bentuk apa pun yang tidak diproses sebelumnya, mis. 8 hingga 10 angka individual, dua daftar nilai yang dipisahkan koma atau dua daftar. Hasilnya dapat dikembalikan atau ditulis ke STDOUT.
Anda mungkin berasumsi bahwa objek-objek itu setidaknya 10 -10 unit panjang terpisah atau berpotongan sebanyak itu, sehingga Anda tidak perlu khawatir tentang keterbatasan tipe floating point.
Ini adalah kode golf, jadi jawaban tersingkat (dalam byte) menang.
Uji Kasus
Mewakili segmen garis dengan 0
, cakram dengan 1
dan lubang 2
, dengan menggunakan format input berbasis daftar, yang berikut ini semua harus menghasilkan output yang benar:
[0,[0,0],[2,2]], [0,[1,0],[2,4]] # Crossing line segments
[0,[0.5,0],[-0.5,0]], [1,[0,0],1] # Line contained in a disc
[0,[0.5,0],[1.5,0]], [1,[0,0],1] # Line partially within disc
[0,[-1.5,0.5],[1.5,0.5]], [1,[0,0],1] # Line cutting through disc
[0,[0.5,2],[-0.5,2]], [2,[0,0],1] # Line outside cavity
[0,[0.5,0],[1.5,0]], [2,[0,0],1] # Line partially outside cavity
[0,[-1.5,0.5],[1.5,0.5]], [2,[0,0],1] # Line cutting through cavity
[1,[0,0],1], [1,[0,0],2] # Disc contained within another
[1,[0,0],1.1], [1,[2,0],1.1] # Intersecting discs
[1,[3,0],1], [2,[0,0],1] # Disc outside cavity
[1,[1,0],0.1], [2,[0,0],1] # Disc partially outside cavity
[1,[0,0],2], [2,[0,0],1] # Disc encircling cavity
[2,[0,0],1], [2,[0,0],1] # Any two cavities intersect
[2,[-1,0],1], [2,[1,0],1] # Any two cavities intersect
sementara yang berikut semua harus menghasilkan output yang salah
[0,[0,0],[1,0]], [0,[0,1],[1,1]] # Parallel lines
[0,[-2,0],[-1,0]], [0,[1,0],[2,0]] # Collinear non-overlapping lines
[0,[0,0],[2,0]], [0,[1,1],[1,2]] # Intersection outside one segment
[0,[0,0],[1,0]], [0,[2,1],[2,3]] # Intersection outside both segments
[0,[-1,2],[1,2]], [1,[0,0],1] # Line passes outside disc
[0,[2,0],[3,0]], [1,[0,0],1] # Circle lies outside segment
[0,[-0.5,0.5],[0.5,-0.5]], [2,[0,0],1] # Line inside cavity
[1,[-1,0],1], [1,[1,1],0.5] # Non-intersecting circles
[1,[0.5,0],0.1], [2,[0,0],1] # Circle contained within cavity
sumber
[0,[-2,0],[-1,0]], [0,[1,0],[2,0]]
Jawaban:
APL,
279208206203Jeda baris dalam fungsi
f
ini untuk kejelasan. Mereka harus diganti dengan pemisah pernyataan⋄
Sudah begitu lama sejak saya terakhir membuat program APL yang begitu kompleks. Saya pikir yang terakhir kali ini tetapi saya bahkan tidak yakin itu serumit.
Format input
Pada dasarnya sama dengan OP, kecuali menggunakan
0
untuk rongga,1
untuk disk dan2
untuk segmen garis.Pembaruan utama
Saya berhasil bermain golf banyak karakter menggunakan algoritma yang berbeda. Tidak ada lagi
g
bulls ** t !!Fungsi utama
f
dibagi menjadi beberapa kasus:2 2≡x
: Segmen-segmenDalam kasus ini, hitung vektor dari titik akhir setiap garis dan pecahkan sistem persamaan linear untuk memeriksa apakah persimpangan tersebut terdapat di dalam vektor.
Peringatan:
Contoh: (Perhatikan peringatan 1 sedang beraksi pada gambar di sebelah kanan)
2≡2⌷x
: Segmen-lainnyaDalam hal ini, objek lainnya adalah yang bundar. Periksa apakah titik akhir segmen berada di dalam lingkaran menggunakan pemeriksaan jarak.
Dalam kasus disk, buat juga segmen garis diameter yang tegak lurus terhadap segmen yang diberikan. Periksa apakah segmen bertabrakan dengan rekursi.
Dalam kasus rongga, menyelinap "kali 0" dalam pembangunan segmen tersebut untuk membuatnya merosot. (Lihat mengapa saya gunakan
0
untuk rongga dan1
untuk disk sekarang?) Karena segmen yang diberikan tidak merosot, deteksi tabrakan segmen-segmen selalu kembali salah.Akhirnya menggabungkan hasil pemeriksaan jarak dan deteksi tabrakan. Untuk kasus rongga, meniadakan hasil pemeriksaan jarak terlebih dahulu. Kemudian (dalam kedua kasus) ATAU 3 hasilnya bersamaan.
Mengenai peringatan segmen-segmen, angka 3 ditujukan (dan dieksploitasi). Nomor 2 bukan masalah karena kami memotong segmen tegak lurus di sini, yang tidak pernah sejajar jika tidak merosot. Nomor 1 berlaku hanya dalam kasus disk, ketika salah satu titik akhir yang diberikan adalah pada diameter yang dibangun. Jika titik akhir berada di dalam lingkaran, pemeriksaan jarak akan menanganinya. Jika titik akhir berada di lingkaran, karena diameter yang dibangun sejajar dengan segmen yang diberikan, yang terakhir harus bersinggungan dengan lingkaran dengan hanya satu titik menyentuh disk, yang bukan merupakan input yang valid.
Contoh:
Kasus bawaan: Lainnya-lainnya
Hitung jarak antara pusat. Tabrakan cakram-cakram terjadi jika dan hanya jika jaraknya lebih kecil dari jumlah jari-jari. Tabrakan rongga cakram terjadi jika dan hanya jika jaraknya lebih besar dari perbedaan jari-jari.
Untuk menangani rongga-rongga, meniadakan hasil pemeriksaan jarak, DAN dengan masing-masing bilangan bulat pengidentifikasi dan kemudian ATAU mereka bersama-sama. Menggunakan beberapa logika, seseorang dapat menunjukkan bahwa proses ini mengembalikan true jika dan hanya jika kedua bilangan bulat mengidentifikasi palsu (kasus rongga-rongga), atau jika pemeriksaan jarak kembali benar
sumber
Javascript - 393 byte
Diperkecil:
Diperluas:
Catatan:
F
yang menerima argumen yang diperlukan dan mengembalikan nilai yang diperlukanF( 0,[[0,0],[2,2]], 0,[[1,0],[2,4]] )
atauF( 1,[[3,0],1], 2,[[0,0],1] )
.sumber
Python, 284
Saya menggunakan algoritma sampah yang cantik dibandingkan dengan semua trik geometrik ini, tetapi ia mendapatkan jawaban yang tepat meskipun dibutuhkan lebih dari satu menit untuk melewati kasus uji. Keuntungan besar adalah bahwa saya hanya perlu menulis tiga fungsi penilaian, dan hillclimbing menangani semua kasus tepi.
Golf:
Tidak Disatukan:
Dan akhirnya, skrip uji jika ada orang yang ingin mencoba ini dengan python:
sumber