コードゴルフ:宇宙船の運命は?[浮動小数点バージョン]


12

この質問は、ASCIIアート版よりも少し難しいです。芸術はありません、そして今、あなたはいくつかの浮動小数点演算をすることができます!

チャレンジ

USS StackExchangeは、船上で天文学的な爆発が発生したときに、惑星cg-00DLEFの重力場を移動していました。船舶のプログラミング責任者として、cg-00DELFの太陽系で土地をcrash落させることを余儀なくされるかどうかを予測するために、船舶の軌道をシミュレートするのがあなたの仕事です。爆発中、船はひどく損傷を受けました。宇宙船の無料のDEEEPRAROM *は限られているため、できるだけ少ない文字でプログラムを作成する必要があります。

*動的に実行可能な電子的に消去可能なプログラマブルランダムアクセス読み取り専用メモリ

シミュレーション

ASCIIアート版にやや似ていますが、タイムステップのアイデアがあります。もう1つのバージョンでは、タイムステップは比較的長い時間でした。船は、1つのタイムステップで惑星の重力をはるかに超えて移動できました。ここで、時間ステップは、距離が大きくなるため、時間の単位がはるかに小さくなります。ただし、1つの大きな違いは、セルが存在しないことです。宇宙船の現在の位置と速度は、関係する重力とともに浮動小数点数になります。もう1つの変更点は、惑星のサイズがはるかに大きくなったことです。

シミュレーションには最大3つの惑星があります。3つすべてに特定の位置、半径、および重力があります。各惑星の重力は、惑星の中心に直接力を加えるベクトルです。このベクトルの強度を求める公式は(Gravity)/(Distance**2)、です。ここで、距離は、船から惑星の中心までの正確な距離です。これは、重力が到達できる場所に制限がないことを意味します。

特定の時間に、宇宙船には速度があります。これは、最後のタイムステップから現在までに移動した距離と角度です。船にも勢いがあります。現在のタイムステップと次のタイムステップの間で移動する距離は、その位置のすべての重力ベクトルに加えられた現在の速度の合計です。これが宇宙船の新しい速度になります。

各シミュレーションには、10000タイムステップの時間制限があります。宇宙船が惑星の内部を移動する場合(惑星の半径よりも惑星の中心に近い場合)、その惑星に衝突します。シミュレーションの終了までに宇宙船がどの惑星にも衝突しない場合、重力から脱出したと推定されます。船が完全に整列し、10001番目のタイムステップで1落しながら10000タイムステップの間軌道にとどまることはまずありません。

入力

入力は、STDINへの4行です。各行は、4つのコンマ区切りの数字で構成されています。数値の形式は次のとおりです。

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

惑星が3つより少ない場合、残りの線はすべての値に対してゼロで埋められます。入力例を次に示します。

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

これは、宇宙船が(60,0)に位置し、10ユニット/タイムステップの速度で「上/北」に直進していることを意味します。2つの惑星があり、1つは(0,0)に、もう1つは(100,100)にあります。どちらも重力が4000で半径が50です。これらはすべて整数ですが、常に整数とは限りません。

出力

出力は、宇宙船がland落したかどうかを伝えるSTDOUTへの1ワードです。船がcrash落した場合、印刷しますcrash。それ以外の場合は、印刷しますescape。上記の入力に対して予想される出力は次のとおりです。

crash

何が起こったのか疑問に思うかもしれません。以下は、宇宙船の詳細な飛行ログを含むPastebinの投稿です。数字は、人々がイベントを視覚化するのを助けるのがあまり得意ではないので、ここで何が起こったのでしょうか?北に移動した後、2番目の惑星の西にわずかに通過し、かろうじて行方不明になります。その後、惑星の北側を曲がり、2番目の惑星の東側に衝突します。

審査のためのいくつかのケース

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!—惑星の重力相互作用はシミュレートされることになっていないのですか?それでも数値的には正確に高価ではありませんが、十分に公平です。—参照シミュレーションでは標準のルンゲクッタ4次統合が使用され、プログラムは同等の結果を作成する必要があると思いますか?
反時計回りの回転を停止

複数の惑星が相互作用する方法を理解していません。問題は、それらがすぐにお互いに衝突する傾向があるということです。これを修正するには、シミュレーションのスケールを非常に大きくする必要があります。
PhiNotPi

Runge-Kutta法に関しては、私は正直、まだ数学が進んでいません。:(船の現在位置で重力を計算し、これを船の速度に加算して、船の新しい速度を生成することでした。タイムステップごとにこれを行いました。これは完全に正確ではないことがわかりましたが、船の開始速度と惑星の重力を10で除算すると、シミュレーションの精度が向上します
PhiNotPi

ああ、それはオイラーの方法でしょう。精度が十分に小さい十分な時間ステップの場合、IMOを実装するには、Runge-Kuttaまたはその他のより洗練された何かがより興味深いでしょう。たぶん私は自分の挑戦を工夫する必要があり、私は...簡単に充足ように見えることはできません
ターンに止まっcounterclockwis

@leftaroundaboutどうぞ。「微分方程式を使用して太陽系全体をシミュレートする」などの空想的なものを作成したり、3次元に追加したりできます。
PhiNotPi

回答:


6

Python、178 170文字

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
今日は複雑な気分ですよね?
counterclockwis回すのをやめ

8
はい、i午前....
キース・ランドール

どうすればそれと競争できますか?
ニール

@ニール:コード、それとも機知に富んだ冗談?
キースランドール

さてコード。私が追いつくことができる機知に富んだ冗談。
ニール

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の第一人者ではありませんが、問題は私の微調整ではありません)。

このソリューションの最初の問題は、GolfScriptとしてのGolfrunには浮動小数点演算がないことです。うまくいけば正しい方法で数字を拡大する「シミュレート」されています(しかし、首尾一貫して行ったことに100%自信はありません)。それでも、ソリューションは入力として浮動小数点数を処理しません。そのため、整数のみを持つように手動で拡大する必要がありました。

Pythonコードでアルゴリズムを実装しようとして、複雑な数学のビットもかなり「一般的な」方法で実装しました。これを回避するためにアルゴリズムを操作したり、可能な限りインライン化したり、定義を遅らせたりすると、他の文字を節約できます...

このコードが機能することをどのように確認できますか?確かに、確かにそうではありません!しかし、サンプルを入力として(それらが現れる場所を「除去」した後)、「コーナーケース」(Pythonでも例外を発生させる)を除いて、期待される結果を書きました...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.