Code Golf: Bagaimana nasib pesawat ruang angkasa? [versi floating point]

12

Pertanyaan ini sedikit lebih sulit daripada versi seni ASCII. Tidak ada seni, dan sekarang Anda bisa melakukan aritmatika floating point!

Tantangan

USS StackExchange bepergian melalui medan gravitasi planet cg-00DLEF ketika sebuah ledakan astronomis terjadi di atas kapal. Sebagai kepala pemrograman kapal, adalah tugas Anda untuk mensimulasikan lintasan kapal Anda untuk memprediksi apakah Anda akan dipaksa untuk menabrak tanah di tata surya cg-00DELF. Selama ledakan, kapal Anda rusak berat. Karena DEEEPRAROM * terbatas dari pesawat ruang angkasa, Anda harus menulis program sesedikit mungkin.

* Secara Acak Dapat Dieksekusi Secara Elektronik, Dapat Diprogram, Akses Acak Hanya Baca Memori

Simulasi

Agak seperti versi seni ASCII, akan ada ide langkah-langkah waktu. Dalam versi lain, langkah waktu adalah jumlah waktu yang relatif besar: kapal dapat melakukan perjalanan jauh melampaui gravitasi sebuah planet dalam satu langkah waktu tunggal. Di sini, langkah waktu adalah satuan waktu yang jauh lebih kecil karena jarak yang lebih jauh. Namun, satu perbedaan utama adalah tidak adanya sel. Lokasi dan kecepatan pesawat ruang angkasa saat ini akan menjadi angka titik mengambang, bersama dengan gaya gravitasi yang terlibat. Perubahan lain adalah kenyataan bahwa planet-planet sekarang memiliki ukuran yang jauh lebih besar.

Akan ada hingga tiga planet dalam simulasi. Ketiganya akan memiliki lokasi, radius, dan gravitasi tertentu. Gravitasi untuk setiap planet adalah vektor yang memberikan kekuatan langsung ke pusat planet. Rumus untuk menemukan kekuatan vektor ini adalah (Gravity)/(Distance**2), di mana jaraknya adalah jarak yang tepat dari kapal ke pusat planet. Ini berarti bahwa tidak ada batasan di mana gravitasi dapat mencapai.

Pada waktu tertentu, pesawat ruang angkasa memiliki kecepatan, yaitu jarak dan sudut yang dilalui dari langkah waktu terakhir ke sekarang. Kapal juga memiliki momentum. Jarak yang akan ia tempuh antara langkah-waktu saat ini dan berikutnya adalah jumlah kecepatan arusnya yang ditambahkan ke semua vektor gravitasi di lokasinya. Ini menjadi kecepatan baru pesawat ruang angkasa.

Setiap simulasi memiliki batas waktu 10.000 langkah waktu. Jika pesawat ruang angkasa berjalan di dalam sebuah planet (lebih dekat ke pusat planet daripada jari-jari planet), maka itu menabrak planet itu. Jika pesawat ruang angkasa tidak menabrak planet mana pun pada akhir simulasi, maka dianggap telah melarikan diri dari gravitasi. Tidak mungkin bahwa kapal itu dapat disejajarkan dengan begitu sempurna sehingga dapat tetap berada di orbit untuk 10.000 langkah waktu saat menabrak langkah waktu 10001.

Memasukkan

Input akan menjadi empat baris ke STDIN. Setiap baris terdiri dari empat angka yang dibatasi koma. Berikut format angka:

ShipLocX,ShipLocY,ShipVelX,ShipVelY
Planet1LocX,Planet1LocY,Planet1Gravity,Planet1Radius
Planet2LocX,Planet2LocY,Planet2Gravity,Planet2Radius
Planet3LocX,Planet3LocY,Planet3Gravity,Planet3Radius

Jika ada kurang dari tiga planet, maka garis sisa akan diisi dengan nol untuk semua nilai. Berikut ini contoh input:

60,0,0,10
0,0,4000,50
100,100,4000,50
0,0,0,0

Ini berarti bahwa pesawat ruang angkasa terletak di (60,0) dan bergerak lurus "ke atas / utara" dengan kecepatan 10 unit / waktu-langkah. Ada dua planet, satu terletak di (0,0) dan satu di (100.100). Keduanya memiliki gravitasi 4000 dan jari-jari 50. Meskipun semua ini adalah bilangan bulat, mereka tidak akan selalu menjadi bilangan bulat.

Keluaran

Output akan menjadi kata tunggal untuk STDOUT untuk mengetahui apakah pesawat ruang angkasa telah jatuh atau tidak. Jika kapal mogok, cetak crash. Kalau tidak, cetak escape. Berikut adalah output yang diharapkan untuk input di atas:

crash

Anda mungkin bertanya-tanya apa yang terjadi. Berikut adalah pos Pastebin yang memiliki log penerbangan terperinci untuk pesawat ruang angkasa. Angka-angka tidak terlalu baik dalam membantu orang memvisualisasikan peristiwa sehingga inilah yang terjadi: Pesawat ruang angkasa berhasil melarikan diri dari gravitasi planet pertama (ke barat) dengan bantuan gravitasi planet kedua (ke timur laut). Bergerak ke utara dan kemudian melewati sedikit ke barat planet kedua, nyaris tidak ada. Kemudian kurva di sekitar sisi utara planet dan menabrak sisi timur planet kedua.

Beberapa kasus lagi untuk diperiksa

60,0,10,-10
0,0,2000,50
100,100,1357.9,47.5
0,0,0,0

melarikan diri (karena hukum kuadrat terbalik, 2000 tidak banyak gravitasi jika Anda 60 unit jauhnya)

0,0,0,0
100,100,20000,140
-50,-50,50,50
-100,-100,50,50

crash (planet pertama sangat besar dan sangat dekat)

0,0,0,0
0,0,0,0
0,0,0,0
0,0,0,0

melarikan diri (ini adalah kasus tepi: tidak ada planet dan interpretasi langsung akan menyarankan bahwa pesawat ruang angkasa langsung di atas planet)

Aturan, Batasan, dan Catatan

Ini golf kode. Aturan golf kode standar berlaku. Program Anda harus ditulis dalam karakter ASCII yang dapat dicetak saja. Anda tidak dapat mengakses segala jenis basis data eksternal. Anda dapat menulis entri dalam bahasa apa pun (selain yang khusus menangani tantangan ini).

Akhiri Transmisi

PhiNotPi
sumber
rofl DEEEPRAROM! - Interaksi gravitasi planet-planet tidak seharusnya disimulasikan? Masih tidak terlalu mahal secara numerik, tapi cukup adil. - Saya menganggap simulasi referensi menggunakan integrasi urutan ke-4 Runge-Kutta standar, dan program kami harus membuat hasil yang setara?
Berhenti menghidupkan counterclockwis
Saya belum menemukan cara melakukan interaksi beberapa planet. Masalahnya adalah mereka akan cenderung saling menabrak segera. Memperbaiki ini akan membutuhkan peningkatan skala simulasi.
PhiNotPi
Adapun metode Runge-Kutta, sejujurnya aku belum mahir dalam matematika. :( Apa yang saya lakukan adalah menghitung gravitasi di lokasi kapal saat ini dan menambahkan ini ke kecepatan kapal, menghasilkan kecepatan baru kapal. Saya melakukan ini untuk setiap langkah waktu. Saya tahu bahwa ini tidak sepenuhnya akurat, tapi saya tahu bahwa membagi kecepatan awal kapal dan gravitasi planet sebesar 10 meningkatkan akurasi simulasi
PhiNotPi
Ah, itu akan menjadi metode Euler. Untuk langkah waktu yang cukup kecil yang akurat, juga; namun Runge-Kutta atau hal lain yang lebih canggih akan lebih menarik untuk diterapkan IMO. Mungkin saya harus menyusun tantangan saya sendiri, saya sepertinya tidak bisa dengan mudah memuaskan ...
berhenti mengubah counterclockwis
@leftaroundabout Silakan. Anda dapat membuat sesuatu seperti "mensimulasikan seluruh tata surya menggunakan persamaan diferensial" atau sesuatu yang mewah seperti itu, atau mungkin menambahkan dimensi ketiga.
PhiNotPi

Jawaban:

6

Python, 178 170 karakter

p=input
a,b,c,d=p()
x=a+b*1j
v=c+d*1j
P=(p(),p(),p())
R='escape'
for i in' '*10000:
 for a,b,g,r in P:
  d=a+b*1j-x;v+=g*d/abs(d)**3
  if abs(d)<r:R='crash'
 x+=v
print R
Keith Randall
sumber
2
Anda dalam suasana hati yang kompleks hari ini, bukan?
Berhenti menghidupkan counterclock
8
ya, isaya ....
Keith Randall
Bagaimana saya bisa bersaing dengan itu?
Neil
@ Neil: kode, atau olok-olok cerdas?
Keith Randall
Nah kodenya. Olok-olok lucu yang bisa saya ikuti.
Neil
2

Golfrun / GolfScript ?, 243 232 karakter

10000:M;n%(','%2/{{~}%}/{{M*}%}:_~:v;_:x;'escape':R;{[','%2/{{~M*}%}/]}%:P;
M,{;P{~\x{0\-}%{+~@+@@+[\]}:|~:d.[~0\-]{[+.2%~*\.-2%~*@\-\.3%~*\(;);~*+]}:&~);~sqrt:z
..**\~d@[`~0]\&@M.*/\{1$/}%v|:v;;z\<{'crash':R;}{}if}/x v|:x;}/R puts

Golfrun adalah bahasa yang sedang saya kerjakan, terlahir sebagai penerjemah GolfScript C, tetapi segera terseret; meskipun saya telah menulis kode ini tanpa menggunakan fitur Golfrun yang disengaja khusus (kecuali untuk sqrt), tes dengan GolfScript asli gagal (saya harus menambahkan fitur sqrt ke kode asli, saya bukan guru Ruby tetapi saya percaya masalahnya adalah bukan tweakeranku).

Masalah pertama dengan solusi ini adalah bahwa Golfrun, seperti GolfScript, tidak memiliki matematika floating point. Ini "disimulasikan" memperbesar angka, semoga dengan cara yang benar (tapi saya tidak 100% yakin saya telah melakukannya secara masuk akal). Meski begitu, solusinya tidak menangani angka floating point sebagai input, jadi saya harus memperbesarnya dengan tangan agar hanya memiliki angka integer.

Mencoba menerapkan algoritma dalam kode Python, saya juga mengimplementasikan bit-bit matematika kompleks dengan cara yang agak "umum". Memanipulasi algoritme untuk menghindari hal ini, dan / atau sebariskan bila memungkinkan, menunda definisi, dapat menghemat karakter lain ...

Bagaimana saya tahu kode ini berfungsi? Memang, saya tidak yakin itu! Tetapi memberikan contoh sebagai input (setelah "menghapus" titik di mana mereka muncul), ia menulis hasil yang diharapkan, kecuali untuk "kasus sudut" (yang menimbulkan pengecualian dalam Python juga) ...

ShinTakezou
sumber