Code Golf: Số phận của tàu vũ trụ là gì? [Phiên bản nghệ thuật ASCII]


14

Lý lịch

Trong một thiên hà (và có thể cả vũ trụ) ở rất xa, rất xa ... có một con tàu vũ trụ và một loạt các hành tinh. Một trục trặc trên tàu khiến tàu vũ trụ hết nhiên liệu. Nó đang di chuyển với tốc độ chậm nguy hiểm gần một cụm hành tinh, từ đó nó phải trốn thoát! Số phận của phi hành đoàn sẽ ra sao?

Các thách thức

Bạn là lập trình viên chính trên USS StackExchange. Như vậy, bạn mong muốn viết một trình giả lập sẽ tiết lộ liệu bạn có cam chịu rơi xuống hành tinh hay không, sẽ thoát khỏi hệ thống hành tinh, hoặc sẽ bị mắc kẹt trong quỹ đạo mãi mãi.

Tuy nhiên, vụ nổ trên tàu vũ trụ của bạn, có nghĩa là tài nguyên tính toán rất hạn chế. Chương trình của bạn phải nhỏ nhất có thể. Ngoài ra, điều này có nghĩa là cách duy nhất có thể để nhập mô phỏng để chạy là thông qua nghệ thuật ASCII.

Mô phỏng

Trong góc phần tư của đa vũ trụ này, các định luật vật lý được thay đổi một chút để phù hợp với nghệ thuật ASCII. Điều này có nghĩa là vũ trụ được chia thành các tế bào. Chuyển động sẽ được mô tả theo đơn vị ô và thời gian sẽ tính theo đơn vị bước thời gian.

Con tàu có đà. Nếu con tàu di chuyển +2 ô trên trục x và -1 ô trên trục y (viết tắt là (2, -1)) trong bước thời gian trước đó và không có trường hấp dẫn, thì con tàu sẽ di chuyển với chính xác cùng vận tốc ở bước tiếp theo.

Sẽ có một số hành tinh, tất cả đều tạo ra một trường hấp dẫn trên tám tế bào ngay lập tức xung quanh nó, điều này sẽ ảnh hưởng đến vận tốc của con tàu và sẽ kéo con tàu đến gần hành tinh hơn. Chỉ là "phía bắc" của một hành tinh sẽ dẫn đến một trường kéo con tàu một ô đến "phía nam" với một lực (-1,0). Chỉ là "phía đông bắc" của một hành tinh sẽ dẫn đến một lực kéo con tàu một ô đến "phía nam" và một đơn vị về phía "tây" với một lực (-1, -1).

Các trường hấp dẫn thêm một vectơ vào động lượng của tàu khi nó rời khỏi tế bào với trọng lực. Nếu một con tàu vừa mới di chuyển (2, -1) ô và hiện đang ở trong trường hấp dẫn của (-1,1), thì trong bước tiếp theo, nó sẽ di chuyển (1,0) ô. Nếu con tàu ở gần nhiều hành tinh, thì sẽ có nhiều vectơ để thêm vào.

Đầu vào

Trên STDIN, bạn sẽ nhận được một đại diện nghệ thuật ASCII của hệ thống hành tinh sẽ hiển thị tọa độ của các hành tinh và vận tốc hiện tại của tàu của bạn. Sẽ có một số hành tinh ở dạng ký hiệu @, trong khi sẽ có một tàu vũ trụ ở dạng ký hiệu av ^ <>. Sự lựa chọn biểu tượng cho con tàu cho biết vận tốc hiện tại của con tàu (trước khi trọng lực đã được thêm vào). Ví dụ: <có nghĩa là vận tốc của một ô ở phía tây, trong khi a ^ có nghĩa là vận tốc của một ô ở phía bắc. Tất cả các không gian trống sẽ bao gồm các khoảng thời gian, đệm mỗi dòng có cùng chiều rộng. Một dòng trống đại diện cho sự kết thúc của đầu vào. Dưới đây là một ví dụ về đầu vào:

.................
...@.@........v..
......@..@..@@...
..@..............
.......@..@......
.................

Đầu ra

Đầu ra sẽ là một từ duy nhất trên STDOUT, nó sẽ cho biết liệu con tàu có thoát khỏi lực hấp dẫn, sẽ đâm vào một hành tinh hay sẽ quay quanh quỹ đạo mãi mãi.

Thoát khỏi trọng lực được định nghĩa là con tàu di chuyển khỏi bản đồ. Nếu tàu thoát ra, thì chương trình của bạn phải in từ "thoát".

Sự cố hạ cánh là khi một con tàu đi trực tiếp qua một hành tinh hoặc kết thúc trong cùng một tế bào trong một bước thời gian. Lưu ý rằng việc tính toán con tàu ở đâu mỗi lần là không đủ. Một con tàu di chuyển với vận tốc (5,5) sẽ đâm vào một hành tinh nằm ở (1,1) mặc dù tính toán đơn giản sẽ có nghĩa là nó sẽ không bao giờ ghé thăm tế bào đó. Tuy nhiên, một con tàu có vận tốc (5,6) sẽ không đâm vào hành tinh. Nếu tàu vũ trụ của bạn gặp sự cố, thì chương trình của bạn phải in từ "sự cố".

Bay quỹ đạo có thể là khó khăn nhất để phát hiện. Sự bay lên xảy ra bất cứ khi nào tàu vũ trụ ghé thăm cùng một tế bào với tốc độ tương tự. Nếu tàu quay quanh quỹ đạo, thì bạn nên in từ "quỹ đạo".

Đây là đầu ra cho ví dụ trên:

escape

Giải trình

Dưới đây là bản đồ cho thấy tàu vũ trụ di chuyển trong mỗi bước thời gian trong ví dụ trên:

   ^
.................
...@.@........v..
....^.@..@..@@...
..@..<.<<<.<.v...
.......@..@......
.................

Nó đi về phía nam, quay về hướng tây, đi xuống một hành lang, quay về hướng bắc và thoát ra một cách hẹp hòi giữa các hành tinh với vận tốc cao, tất cả đều là lực hấp dẫn.


Nhiều trường hợp để kiểm tra

...
^@.
...
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)

Các quy tắc, quy định và ghi chú

Đây là mã golf. Quy tắc golf tiêu chuẩn áp dụng. Các chương trình của bạn phải được viết bằng ASCII có thể in được. Bạn không được phép truy cập bất kỳ loại cơ sở dữ liệu bên ngoài.

Kết thúc truyền


Dường như có một lỗi đánh máy trong dòng ngay phía trên phần INPUT ... Tôi giả sử bạn có nghĩa là hành tinh? :-)
Gaffi

Trên thực tế, toàn bộ đoạn một phần cần phải được xóa, thông tin được lặp lại dưới phần đầu ra.
PhiNotPi

1
Tôi muốn điều này tốt hơn với vật lý ít thay đổi một chút ... trang web này có thể giải quyết được nhiều vấn đề hơn cũng liên quan đến số học dấu phẩy động đắt tiền.
đã ngừng quay ngược chiều

1
@leftaroundabout Đó có thể là thử thách tiếp theo của tôi.
PhiNotPi

Làm thế nào gần với một hành tinh cần phải được đâm vào nó?
Peter Taylor

Câu trả lời:


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");}}

Phiên bản chưa được chỉnh sửa (và được tái cấu trúc một chút) có sẵn tại http://pastebin.com/yAKYvwQf

Phiên bản đang chạy: https://compilify.net/1n9 Điều này đã được sửa đổi một chút để được chạy trên phàn nàn:

  • không tạo mảng ẩn - ví dụ: new[]{1,2}
  • sử dụng return <string>thay vì Console.WriteLine, vì đó là cách compilify.net hoạt động
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.