Code Golf:宇宙飞船的命运是什么?[ASCII艺术版本]


14

背景

在一个遥远的星系(可能还有一个宇宙)中……有一艘太空船和一堆行星。船上的故障导致飞船的燃料用完了。它现在正以危险的缓慢速度在附近的行星簇附近移动,必须从中逃脱!机组人员的命运是什么?

挑战

您是USS StackExchange的首席程序员。因此,您希望编写一个模拟器来揭示您是否注定要坠落到行星上,逃离行星系统或永远停留在轨道上。

但是,您的飞船爆炸了,这意味着计算资源非常有限。您的程序必须尽可能小。同样,这意味着输入要运行的仿真的唯一可能方法是通过ASCII艺术。

模拟

在多元宇宙的这一象限中,为了适应ASCII艺术,对物理定律做了些微改动。这意味着宇宙被分为细胞。运动将以单元为单位进行描述,时间将以时间步长为单位。

船本身有动力。如果船在上一个时间步中在x轴上移动了+2个像元,在y轴上移动了-1个像元(简称为(2,-1)),并且没有重力场,则该船将按照在下一个时间步中保持相同的速度。

将有几颗行星,所有这些行星都在紧邻其的八个单元上施加引力场,这将影响船的速度并将船拉近行星。正好位于行星的“北”,会导致以(-1,0)的力将飞船的一个单元向“南”拉。只是行星的“东北”,将导致以(-1,-1)的力将飞船一个单元拉向“南”,将一个单元拉向“西”。

重力场为船舶离开重力时的动量增加了一个矢量。如果一艘船以前移动了(2,-1)个像元,而现在处于(-1,1)的重力场中,那么在下一个步骤中,它将移动(1,0)个像元。如果船靠近多个行星,则将添加多个矢量。

输入值

在STDIN上,您将收到行星系统的ASCII艺术作品表示,它将显示行星的坐标和船的当前速度。将有多个@符号形式的行星,而将有一个以av ^ <>符号形式的宇宙飞船。选择船的符号表示船的当前速度(在添加重力之前)。例如,<表示一个单元向西的速度,而^表示一个单元向北的速度。所有空白区域都由句点组成,这些句点将每行填充为相同的宽度。空行代表输入的结尾。这是输入的示例:

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

输出量

输出将是STDOUT上的一个字,它将告诉船是逃避重力,坠落到行星上还是永远绕轨道运行。

逃避重力的定义是船舶从地图上移开。如果船逃脱,那么您的程序必须打印单词“ escape”。

崩溃着陆是指船舶在某个时间步中直接越过行星或在同一单元中结束时。请注意,仅计算船舶每个时间段的位置是不够的。速度为(5,5)的船舶将撞向位于(1,1)的行星,即使直接计算将意味着它永远也不会访问该单元。但是,速度为(5,6)的飞船不会撞到地球上。如果您的飞船坠毁着陆,那么您的程序必须打印“ crash”一词。

轨道运动可能是最难检测到的。每当飞船以相同的速度两次访问相同的单元时,就会发生轨道运动。如果飞船绕行,则应打印单词“ orbit”。

这是以上示例的输出:

escape

说明

这是一张地图,显示上例中太空船在每个时间步中的移动位置:

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

它向南走,向西走,沿着走廊走,向北走,然后由于重力而狭窄地逃到了高速行星之间。


更多案件要检查

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

规则,规定和注释

这是代码高尔夫。适用标准代码高尔夫规则。您的程序必须使用可打印的ASCII编写。不允许您访问任何类型的外部数据库。

结束传输


在“输入”部分上方的行中似乎有一个错字...我认为您是说行星吗?:-)
加菲2012年

实际上,整个部分段落都需要删除,该信息在输出部分下重复出现。
PhiNotPi 2012年

1
我希望物理变化稍少一点更好。此站点可以解决更多问题,其中还涉及一些不错的昂贵的浮点算法。
停止

1
@leftaroundabout这可能是我的下一个挑战。
PhiNotPi 2012年

撞入行星需要离行星多近?
彼得·泰勒

Answers:


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

可在http://pastebin.com/yAKYvwQf上获得非高尔夫版本(略微重构)的版本

运行版本:https ://compilify.net/1n9此版本经过稍加修改,可以在complify上运行:

  • 没有隐式数组创建-例如: new[]{1,2}
  • 使用return <string>代替Console.WriteLine,因为compilify.net就是这样工作的
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.