Code Golf:宇宙飞船的命运是什么?[浮点版本]


12

这个问题比ASCII艺术版本要难一些。没有艺术,现在您可以进行浮点运算了!

挑战

当船上发生天文爆炸时,USS StackExchange正在穿越cg-00DLEF行星的重力场。作为该船的首席程序设计官,您的工作是模拟船的轨迹,以预测您是否会被迫撞倒cg-00DELF的太阳系中的土地。在爆炸期间,您的船严重受损。由于飞船的免费DEEEPRAROM *有限,因此您必须以尽可能少的字符编写程序。

*动态可执行电子擦除可编程随机存取只读存储器

模拟

有点像ASCII艺术版本,会有时间步伐的想法。在另一个版本中,时间步长是相对较长的时间:船舶可以在单个时间步长中超越行星的重力行进。在此,由于所涉及的距离较大,因此时间步长要小得多。然而,一个主要的区别是不存在细胞。飞船的当前位置和速度将是浮点数,以及所涉及的重力。另一个变化是,行星现在的尺寸更大。

模拟中最多有三个行星。这三个都将具有特定的位置,半径和重力。每个行星的重力是一个向量,直接向行星中心施加力。查找该矢量强度的公式为(Gravity)/(Distance**2),其中距离是从船到行星中心的精确距离。这意味着重力可以到达的地方没有限制。

在任何特定时间,飞船都有一个速度,即它从最后一个时间步到现在的距离和角度。该船也有动力。它在当前时间步与下一时间步之间行进的距离是其当前速度加到该位置所有重力矢量的总和。这成为飞船的新速度。

每个模拟的时间限制为10000个时间步。如果太空飞船在行星内部移动(比行星的半径更靠近行星的中心),则它会撞入该行星。如果到模拟结束时飞船没有坠入任何行星,则可以认为它已脱离重力。这艘船不可能如此完美地对准,以至于它能够在10000个时间步长上坠毁而设法在轨道上停留10000个时间步长。

输入值

输入到STDIN的四行。每行由四个逗号分隔的数字组成。这是数字的格式:

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

如果少于三个行星,则剩余线将对所有值填充零。这是一个示例输入:

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

这意味着太空飞船位于(60,0),并且以“ 10个单位/时间步长”的速度直线“向上/向北”行驶。有两颗行星,一颗位于(0,0),另一颗位于(100,100)。两者的重力为4000,半径为50。即使所有这些都是整数,它们也不总是整数。

输出量

输出将是一个字到STDOUT,以告诉飞船是否坠毁。如果船舶坠毁,请打印crash。否则,请打印escape。这是上述输入的预期输出:

crash

您可能想知道发生了什么。是一个Pastebin帖子,其中包含该飞船的详细飞行日志。数字并不能很好地帮助人们可视化事件,所以这是发生了什么:飞船设法借助第二个行星(向东北)的引力逃脱了第一个行星(向西)的引力。它向北移动,然后略微经过第二个行星的西面,几乎没有丢失它。然后,它绕行星的北侧弯曲并撞向第二颗行星的东侧。

其他一些案件进行检查

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

逃逸(由于平方反比定律,如果您离60个单位远,则2000重力不大)

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

坠毁(第一颗行星非常巨大且非常接近)

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

逃脱(这是一个极端的情况:没有行星,直接的解释将表明飞船直接在行星的顶部)

规则,限制和注释

这是代码高尔夫。适用标准代码高尔夫规则。您的程序只能用可打印的ASCII字符编写。您无法访问任何类型的外部数据库。您可以用任何语言(除了专门用于解决此挑战的语言)编写条目。

结束传输


rofl DEEEPRAROM!—不应模拟行星的引力相互作用吗?那时在数字上仍然不算很贵,但足够公平。—我假设参考仿真使用标准的Runge-Kutta四阶积分,并且我们的程序必须创建等效的结果吗?
停止了逆时针旋转

我还没有弄清楚如何使多个行星相互作用。问题在于它们往往会立即崩溃。要解决此问题,将需要极大地提高模拟的规模。
PhiNotPi 2012年

至于Runge-Kutta方法,老实说,我在数学上还没有那么先进。:(我所做的是计算船舶当前位置的重力并将其添加到船舶速度中,从而生成船舶的新速度。我在每个时间步上都进行了此操作。我知道这并不完全准确,但是我发现了将船的起始速度和行星的重力除以10可以提高模拟的准确性
PhiNotPi 2012年

嗯,那就是欧拉的方法。对于足够小的时间步长,它也是准确的;但是Runge-Kutta或其他更复杂的方法对于实施IMO会更加有趣。也许我应该设计自己的挑战,我似乎无法轻易满足……
不再转向逆时针

@leftaroundabout继续。您可以进行诸如“使用微分方程模拟整个太阳系”之类的东西,或者类似的东西,或者可以添加第三维。
PhiNotPi 2012年

Answers:


6

Python,178170个字符

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

2
今天你心情复杂,不是吗?

8
是的,i是...
基思·兰德尔

我该如何竞争?
尼尔

@Neil:代码,还是风趣的玩笑?
基思·兰德尔

好的代码。我可以跟得上机智的玩笑。
尼尔2012年

2

Golfrun / GolfScript ?, 243 232个字符

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是我正在使用的一种语言,最初是GolfScript C解释器,但很快就消失了。尽管我在编写代码时没有使用已知的特定Golfrun功能(除外sqrt),但是使用原始GolfScript进行的测试失败了(我必须在原始代码中添加sqrt功能,我不是Ruby专家,但我认为问题是不是我的调整)。

该解决方案的第一个问题是,Golfrun作为GolfScript,没有浮点数学运算。它是“模拟”的,希望以正确的方式放大数字(但我不是100%确信我已经一致地做到了)。即使这样,该解决方案也不能将浮点数作为输入处理,因此我不得不手动将它们放大为仅具有整数。

尝试在Python代码中实现该算法,我还以一种相当“通用”的方式实现了一些复杂的数学运算。为避免这种情况而操纵算法,和/或尽可能地内联,延迟定义,可以节省其他字符。

我怎么知道此代码有效?的确,我不确定是否确实如此!但是,将示例作为输入(在“删除”它们出现的位置之后),它编写了预期的结果,除了“ corner case”(在Python中也引发了异常)...

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.