Code Golf: Bagaimana nasib pesawat ruang angkasa? [Versi seni ASCII]

14

Latar Belakang

Di galaksi (dan mungkin alam semesta) jauh, jauh ... ada pesawat ruang angkasa dan sekelompok planet. Kerusakan di kapal menyebabkan pesawat ruang angkasa kehabisan bahan bakar. Sekarang bergerak dengan kecepatan lambat berbahaya di dekat sekelompok planet, dari mana ia harus melarikan diri! Apa nasib kru?

Tantangan

Anda adalah programmer utama di USS StackExchange. Dengan demikian, Anda berhasrat untuk menulis simulator yang akan mengungkapkan apakah Anda ditakdirkan untuk menabrak daratan atau tidak, akan melarikan diri dari sistem planet, atau akan terjebak di orbit selamanya.

Namun, ledakan pada pesawat ruang angkasa Anda berarti ada sumber daya komputasi yang sangat terbatas. Program Anda harus sekecil mungkin. Juga, ini berarti bahwa satu-satunya cara memasukkan simulasi yang mungkin dijalankan adalah melalui ASCII art.

Simulasi

Di kuadran multiverse ini, hukum fisika sedikit diubah untuk mengakomodasi seni ASCII. Ini berarti bahwa kosmos dibagi menjadi sel. Gerakan akan dijelaskan dalam satuan sel, dan waktu akan dalam satuan langkah waktu.

Kapal itu sendiri memiliki momentum. Jika kapal memindahkan +2 sel pada sumbu x dan -1 sel pada sumbu y (disingkat menjadi (2, -1)) pada langkah waktu sebelumnya, dan tidak ada medan gravitasi, maka kapal akan bergerak dengan tepat kecepatan yang sama pada langkah waktu berikutnya.

Akan ada beberapa planet, yang semuanya mengerahkan medan gravitasi pada delapan sel yang mengelilinginya, yang akan mempengaruhi kecepatan kapal dan akan menarik kapal lebih dekat ke planet ini. Menjadi "utara" dari sebuah planet akan menghasilkan bidang menarik kapal satu sel ke "selatan" dengan kekuatan (-1,0). Menjadi "timur laut" dari sebuah planet akan menghasilkan gaya yang menarik kapal satu sel ke "selatan" dan satu unit ke "barat" dengan kekuatan (-1, -1).

Medan gravitasi menambahkan vektor pada momentum kapal karena meninggalkan sel dengan gravitasi. Jika sebuah kapal yang sebelumnya bergerak (2, -1) sel dan sekarang berada dalam medan gravitasi (-1,1), maka pada langkah selanjutnya ini akan memindahkan (1,0) sel. Jika kapal berdekatan dengan beberapa planet, maka akan ada beberapa vektor untuk ditambahkan.

Memasukkan

Di STDIN, Anda akan menerima representasi seni ASCII dari sistem planet yang akan menunjukkan koordinat planet-planet dan kecepatan kapal Anda saat ini. Akan ada beberapa planet dalam bentuk tanda @, sementara akan ada satu pesawat ruang angkasa dalam bentuk tanda av ^ <>. Pilihan simbol untuk kapal menunjukkan kecepatan kapal saat ini (sebelum gravitasi ditambahkan). Sebagai contoh, a berarti kecepatan satu sel ke barat, sedangkan a = kecepatan satu sel ke utara. Semua ruang kosong akan terdiri dari titik-titik, yang mengisi setiap garis dengan lebar yang sama. Baris kosong mewakili akhir input. Berikut ini contoh input:

.................
...@[email protected]..
......@..@..@@...
..@..............
.......@..@......
.................

Keluaran

Output akan menjadi kata tunggal pada STDOUT, yang akan memberi tahu apakah kapal akan lepas gravitasi, akan menabrak daratan ke sebuah planet, atau akan mengorbit selamanya.

Melarikan diri dari gravitasi didefinisikan sebagai kapal yang bergerak keluar dari peta. Jika kapal lolos, maka program Anda harus mencetak kata "escape".

Crash landing adalah ketika sebuah kapal melewati langsung sebuah planet atau berakhir di sel yang sama selama langkah waktu. Perhatikan bahwa tidak cukup hanya menghitung di mana kapal setiap langkah waktu. Sebuah kapal yang bergerak dengan kecepatan (5,5) akan menabrak sebuah planet yang terletak di (1,1) meskipun perhitungan langsung berarti bahwa ia tidak akan pernah mengunjungi sel itu. Namun, kapal dengan kecepatan (5,6) tidak akan menabrak daratan ke planet ini. Jika crash pesawat ruang angkasa Anda mendarat, maka program Anda harus mencetak kata "crash".

Mengorbit mungkin yang paling sulit dideteksi. Pengorbit terjadi setiap kali pesawat ruang angkasa mengunjungi sel yang sama dua kali dan dengan kecepatan yang sama. Jika kapal mengorbit, maka Anda harus mencetak kata "orbit".

Berikut ini adalah output untuk contoh di atas:

escape

Penjelasan

Berikut ini adalah peta yang menunjukkan tempat pesawat ruang angkasa bepergian di setiap langkah waktu dalam contoh di atas:

   ^
.................
...@[email protected]..
....^.@..@..@@...
..@..<.<<<.<.v...
.......@..@......
.................

Ia pergi ke selatan, berbelok ke barat, melakukan perjalanan menyusuri koridor, berbelok ke utara, dan nyaris lolos ke planet-planet dengan kecepatan tinggi, semuanya karena gravitasi.


Lebih banyak kasus untuk diperiksa

...
^@.
...
orbit
...........
.>@.@......
.@......@..
....@......
crash (it crashes into the easternmost planet)
...
.@.
.v.
crash (momentum can't overcome gravity)
........
..@.....
..<.....
...@....
........
orbit (it gets trapped in a gravity well between two planets)

Aturan, Peraturan, dan Catatan

Ini golf kode. Aturan golf kode standar berlaku. Program Anda harus ditulis dalam ASCII yang dapat dicetak. Anda tidak diizinkan mengakses segala jenis basis data eksternal.

Akhiri Transmisi

PhiNotPi
sumber
Tampaknya ada kesalahan ketik pada baris tepat di atas bagian INPUT ... Saya berasumsi maksudmu planet? :-)
Gaffi
Sebenarnya, seluruh paragraf parsial itu perlu dihapus, informasinya diulangi di bagian keluaran.
PhiNotPi
1
Saya ingin ini lebih baik dengan fisika yang sedikit berubah ... situs ini dapat melakukan lebih banyak masalah yang juga melibatkan aritmatika titik apung yang sedikit mahal.
Berhenti menghidupkan counterclockwis
1
@leftaroundabout Itu mungkin tantangan saya berikutnya.
PhiNotPi
Seberapa dekat dengan sebuah planet dengan menabraknya?
Peter Taylor

Jawaban:

6

C # 991 984

struct P{public P(int x,int y){X=x;Y=y;}public int X,Y;}
class O:Exception{}
class C:O{}
List<P>p=new List<P>();
List<string>h=new List<string>();
P r,v,u;
void S(){
var i=0;
for(var l=Console.ReadLine();l!="";l=Console.ReadLine())
{u.X=l.Select((c,j)=>
{if(c=='@')p.Add(new P(j,i));else if(c!='.')
{r=new P(j,i);v=(c=='v'?new P(0,1):c=='<'?new P(-1,0):c=='^'?new P(0,-1):new P(1,0));}
return u;}).Count();i++;}
u.Y=i;
var x=new Action<string>(Console.WriteLine);
try{
while(true){
p.ForEach(q=>{var a=q.X-r.X;var b=q.Y-r.Y;
if(a<2&&a>-2&&b<2&&b>-2){v.X+=a;v.Y+=b;}});
var c=string.Join(".",r.X,r.Y,v.X,v.Y);
if(h.Contains(c))throw new O();
h.Add(c);
var z=new P(r.X,r.Y);var k=new[]{v.X,v.Y};var m=k.Min();var M=k.Max();
for(var j=1;j<=M;j++)
if((j*m)%M==0){
if(p.Contains(new P(z.X+(v.X==M?j:j*m/M),z.Y+(v.Y==M?j:j*m/M))))throw new C();}
r.X+=v.X;r.Y+=v.Y;
if(r.X<0||r.X>=u.X||r.Y<0||r.Y>=u.Y)throw new Exception();}}
catch(C){x("crush");}
catch(O){x("orbit");}
catch{x("escape");}}

Versi ungolfed (dan sedikit refactored) tersedia di http://pastebin.com/yAKYvwQf

Versi yang sedang berjalan: https://compilify.net/1n9 Ini telah sedikit dimodifikasi untuk dijalankan pada komplain:

  • tidak ada pembuatan array implisit - mis: new[]{1,2}
  • menggunakan return <string>bukan Console.WriteLine, karena itulah cara kerja compilify.net
Cristian Lupascu
sumber