Code Golf: Was ist das Schicksal des Raumschiffs? [Gleitkomma-Version]

12

Diese Frage ist etwas schwieriger als die ASCII-Art-Version. Es gibt keine Kunst, und jetzt können Sie Gleitkomma-Arithmetik machen!

Die Herausforderung

Die USS StackExchange bewegte sich durch das Gravitationsfeld des Planeten cg-00DLEF, als an Bord eine astronomische Explosion auftrat. Als Chefprogrammierer des Schiffes ist es Ihre Aufgabe, die Flugbahn Ihres Schiffes zu simulieren, um vorherzusagen, ob Sie gezwungen sind, im Sonnensystem von cg-00DELF zu landen. Während der Explosion wurde Ihr Schiff schwer beschädigt. Aufgrund des begrenzten freien DEEEPRAROM * des Raumschiffs müssen Sie Ihr Programm in möglichst wenigen Zeichen schreiben.

* Dynamisch ausführbarer elektronisch löschbarer programmierbarer Nur-Lese-Speicher mit wahlfreiem Zugriff

Die Simulation

Ähnlich wie bei der ASCII-Art-Version wird es die Idee von Zeitschritten geben. In der anderen Version war ein Zeitschritt relativ viel Zeit: Das Schiff konnte sich in einem einzigen Zeitschritt weit über die Schwerkraft eines Planeten hinausbewegen. Hier ist der Zeitschritt aufgrund der größeren Entfernungen eine viel kleinere Zeiteinheit. Ein wesentlicher Unterschied ist jedoch das Fehlen von Zellen. Die aktuelle Position und Geschwindigkeit des Raumschiffs sind Gleitkommazahlen, zusammen mit den Gravitationskräften. Eine weitere Änderung ist die Tatsache, dass Planeten jetzt viel größer sind.

Es werden bis zu drei Planeten in der Simulation sein. Alle drei haben eine bestimmte Position, einen bestimmten Radius und eine bestimmte Schwerkraft. Die Schwerkraft für jeden Planeten ist ein Vektor, der eine Kraft direkt in Richtung des Mittelpunkts des Planeten ausübt. Die Formel zum Ermitteln der Stärke dieses Vektors lautet (Gravity)/(Distance**2), wobei die Entfernung die genaue Entfernung vom Schiff zum Mittelpunkt des Planeten ist. Dies bedeutet, dass der Schwerkraft keine Grenzen gesetzt sind.

Zu einem bestimmten Zeitpunkt hat das Raumschiff eine Geschwindigkeit, die die Entfernung und den Winkel angibt, die es vom letzten Zeitschritt bis jetzt zurückgelegt hat. Das Schiff hat auch Schwung. Die Entfernung, die es zwischen dem aktuellen und dem nächsten Zeitschritt zurücklegen wird, ist die Summe seiner aktuellen Geschwindigkeit, die zu allen Schwerkraftvektoren an seiner Position addiert wird. Dies wird die neue Geschwindigkeit des Raumschiffs.

Jede Simulation hat ein Zeitlimit von 10000 Zeitschritten. Wenn sich das Raumschiff innerhalb eines Planeten bewegt (näher am Mittelpunkt des Planeten als am Radius des Planeten), stürzt es auf diesen Planeten ab. Wenn das Raumschiff bis zum Ende der Simulation nicht auf einen Planeten stürzt, wird angenommen, dass es der Schwerkraft entkommen ist. Es ist unwahrscheinlich, dass das Schiff so perfekt ausgerichtet werden kann, dass es 10000 Zeitschritte im Orbit bleibt, während es auf dem 10001. Zeitschritt abstürzt.

Eingang

Die Eingabe erfolgt über vier Leitungen nach STDIN. Jede Zeile besteht aus vier durch Kommas getrennten Zahlen. Hier ist das Format der Zahlen:

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

Wenn es weniger als drei Planeten gibt, werden die verbleibenden Linien für alle Werte mit Nullen gefüllt. Hier ist eine Beispieleingabe:

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

Dies bedeutet, dass sich das Raumschiff bei (60,0) befindet und sich mit einer Geschwindigkeit von 10 Einheiten / Zeitschritt geradeaus "nach oben / Norden" bewegt. Es gibt zwei Planeten, einen bei (0,0) und einen bei (100,100). Beide haben eine Schwerkraft von 4000 und einen Radius von 50. Obwohl alle diese Zahlen Ganzzahlen sind, werden sie nicht immer Ganzzahlen sein.

Ausgabe

Die Ausgabe wird ein einzelnes Wort an STDOUT sein, um festzustellen, ob das Raumschiff abgestürzt ist oder nicht. Wenn das Schiff abstürzt, drucken Sie crash. Andernfalls drucken escape. Hier ist die erwartete Ausgabe für die obige Eingabe:

crash

Sie fragen sich vielleicht, was passiert ist. Hier ist ein Pastebin-Beitrag mit einem detaillierten Flugbuch für das Raumschiff. Die Zahlen helfen den Menschen nicht sehr gut, das Ereignis zu visualisieren, und so geschah Folgendes: Das Raumschiff schafft es, mit Hilfe der Schwerkraft des zweiten Planeten (im Nordosten) der Schwerkraft des ersten Planeten (im Westen) zu entkommen. Es bewegt sich nach Norden und verläuft dann leicht westlich des zweiten Planeten, wobei es kaum fehlt. Es krümmt sich dann um die Nordseite des Planeten und stürzt gegen die Ostseite des zweiten Planeten.

Einige weitere Fälle zur Prüfung

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

Flucht (aufgrund des inversen Quadratgesetzes ist 2000 nicht viel Schwerkraft, wenn Sie 60 Einheiten entfernt sind)

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

Absturz (der erste Planet ist extrem massiv und extrem nah)

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

Flucht (dies ist ein Randfall: Es gibt keine Planeten und eine einfache Interpretation würde nahelegen, dass sich das Raumschiff direkt über den Planeten befindet.)

Regeln, Einschränkungen und Hinweise

Das ist Code Golf. Es gelten die Standard-Code-Golfregeln. Ihr Programm sollte nur in druckbaren ASCII-Zeichen geschrieben werden. Sie können auf keine externe Datenbank zugreifen. Sie können Einträge in einer beliebigen Sprache verfassen (außer einer, die auf die Lösung dieser Herausforderung spezialisiert ist).

Übertragung beenden

PhiNotPi
quelle
rofl DEEEPRAROM! - Die Gravitationswechselwirkung der Planeten soll nicht simuliert werden? Immer noch nicht gerade teuer, aber fair genug. - Ich gehe davon aus, dass die Referenzsimulation die Standardintegration Runge-Kutta 4. Ordnung verwendet und unser Programm äquivalente Ergebnisse liefern muss.
drehte sich nicht mehr gegen den Uhrzeigersinn am
Ich habe nicht herausgefunden, wie mehrere Planeten interagieren. Das Problem ist, dass sie dazu neigen, einfach sofort ineinanderzustoßen. Um dies zu beheben, muss der Maßstab der Simulation enorm vergrößert werden.
PhiNotPi
Was die Runge-Kutta-Methode betrifft, bin ich ehrlich gesagt noch nicht so weit fortgeschritten in Mathe. :( Was ich getan habe, war die Schwerkraft am aktuellen Standort des Schiffes zu berechnen und diese zur Schiffsgeschwindigkeit zu addieren, um die neue Schiffsgeschwindigkeit zu generieren. Ich habe dies für jeden Zeitschritt getan. Ich weiß, dass dies nicht ganz genau ist, aber ich habe es herausgefunden Das Teilen der Startgeschwindigkeit des Schiffes und der Schwerkraft der Planeten durch 10 erhöht die Genauigkeit der Simulation
PhiNotPi
Ah, das wäre Eulers Methode. Bei genügend kleinen Zeitschritten ist man auch genau; Runge-Kutta oder etwas anderes Raffinierteres wäre interessanter, um IMO zu implementieren. Vielleicht sollte ich mir meine eigene Herausforderung ausdenken, ich kann nicht leicht zu befriedigen sein ...
aufgehört, mich gegen den Uhrzeigersinn zu drehen, am
@leftaroundabout Mach weiter. Sie können so etwas wie "das gesamte Sonnensystem mit Hilfe von Differentialgleichungen simulieren" oder etwas Ähnliches machen oder vielleicht in der dritten Dimension hinzufügen.
PhiNotPi

Antworten:

6

Python, 178 170 Zeichen

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
Keith Randall
quelle
2
Sie sind heute in einer komplexen Stimmung, nicht wahr?
hörte auf, gegen den Uhrzeigersinn am
8
ja ibin ....
Keith Randall
Wie kann ich damit konkurrieren?
Neil
@Neil: der Code oder der witzige Scherz?
Keith Randall
Na der Code. Der witzige Scherz, mit dem ich mithalten kann.
Neil
2

Golfrun / GolfScript ?, 243 232 Zeichen

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 ist eine Sprache, an der ich arbeite, die als GolfScript C-Interpreter geboren wurde, aber bald irgendwohin abdriftete. Obwohl ich diesen Code geschrieben habe, ohne wissentlich bestimmte Golfrun-Funktionen zu verwenden (außer sqrt), schlug der Test mit dem ursprünglichen GolfScript fehl (ich musste die sqrt-Funktion zum ursprünglichen Code hinzufügen), bin ich kein Ruby-Guru, aber ich glaube, das Problem ist nicht mein Tweaking).

Das erste Problem bei dieser Lösung ist, dass Golfrun, wie GolfScript, keine Gleitkomma-Mathematik hat. Es wird "simuliert", um die Zahlen zu vergrößern, hoffentlich auf die richtige Weise (aber ich bin nicht zu 100% sicher, dass ich es kohärent gemacht habe). Trotzdem behandelt die Lösung Gleitkommazahlen nicht als Eingabe, so dass ich sie manuell vergrößern musste, um nur ganzzahlige Zahlen zu erhalten.

Beim Versuch, den Algorithmus im Python-Code zu implementieren, habe ich auch komplexe mathematische Elemente eher "allgemein" implementiert. Das Manipulieren des Algorithmus, um dies zu vermeiden, und / oder Inlining, wenn möglich, das Verzögern der Definitionen, könnte andere Zeichen einsparen ...

Woher weiß ich, dass dieser Code funktioniert? Tatsächlich bin ich mir nicht sicher, ob es so ist! Wenn Sie jedoch die Beispiele als Eingabe angeben (nachdem Sie die Punkte, an denen sie angezeigt werden, "entfernt" haben), wurden die erwarteten Ergebnisse geschrieben, mit Ausnahme des "Eckfalles" (der auch in Python eine Ausnahme auslöst) ...

ShinTakezou
quelle