Code Golf: quel est le sort du vaisseau spatial? [version à virgule flottante]

12

Cette question est légèrement plus difficile que la version art ASCII. Il n'y a pas d'art, et maintenant vous pouvez faire de l'arithmétique à virgule flottante!

Le défi

L'USS StackExchange voyageait à travers le champ de gravité de la planète cg-00DLEF lorsqu'une explosion astronomique s'est produite à bord. En tant qu'officier en chef de la programmation du navire, il vous appartient de simuler la trajectoire de votre navire afin de prédire si vous serez obligé de s'écraser sur le système solaire du cg-00DELF. Pendant l'explosion, votre navire a été lourdement endommagé. En raison du DEEEPRAROM * limité et limité du vaisseau spatial, vous devez écrire votre programme en aussi peu de caractères que possible.

* Mémoire en lecture seule programmable, effaçable électroniquement et effaçable électroniquement

La simulation

Un peu comme la version art ASCII, il y aura l'idée de pas de temps. Dans l'autre version, un pas de temps était une quantité de temps relativement importante: le navire pouvait voyager bien au-delà de la gravité d'une planète en un seul pas de temps. Ici, le pas de temps est une unité de temps beaucoup plus petite en raison des plus grandes distances impliquées. Une différence majeure, cependant, est la non-existence de cellules. L'emplacement et la vitesse actuels du vaisseau spatial seront des nombres à virgule flottante, ainsi que les forces gravitationnelles impliquées. Un autre changement est le fait que les planètes ont maintenant une taille beaucoup plus grande.

Il y aura jusqu'à trois planètes dans la simulation. Les trois auront un emplacement, un rayon et une gravité spécifiques. La gravité de chaque planète est un vecteur qui exerce une force directement vers le centre de la planète. La formule pour trouver la force de ce vecteur est (Gravity)/(Distance**2), où la distance est la distance exacte du navire au centre de la planète. Cela signifie qu'il n'y a pas de limite à l'endroit où la gravité peut atteindre.

À tout moment spécifique, le vaisseau spatial a une vitesse, qui est la distance et l'angle qu'il a parcouru du dernier pas de temps à maintenant. Le navire a également une dynamique. La distance qu'il parcourra entre le pas de temps actuel et le suivant est la somme de sa vitesse actuelle ajoutée à tous les vecteurs de gravité à son emplacement. Cela devient la nouvelle vitesse du vaisseau spatial.

Chaque simulation a une limite de temps de 10000 pas de temps. Si le vaisseau spatial se déplace à l'intérieur d'une planète (il est plus proche du centre de la planète que du rayon de la planète), alors il s'écrase sur cette planète. Si le vaisseau spatial ne s'écrase sur aucune planète à la fin de la simulation, il est alors présumé s'être échappé de la gravité. Il est peu probable que le navire puisse être aligné si parfaitement qu'il parvienne à rester en orbite pendant 10000 pas de temps tout en s'écraser sur le 10001e pas de temps.

Contribution

L'entrée sera de quatre lignes vers STDIN. Chaque ligne se compose de quatre nombres séparés par des virgules. Voici le format des nombres:

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

S'il y a moins de trois planètes, les lignes restantes seront remplies de zéros pour toutes les valeurs. Voici un exemple d'entrée:

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

Cela signifie que le vaisseau spatial est situé à (60,0) et se déplace tout droit "vers le haut / nord" à un taux de 10 unités / pas de temps. Il y a deux planètes, une située à (0,0) et une à (100,100). Les deux ont une gravité de 4000 et un rayon de 50. Même si tous ces éléments sont des entiers, ils ne seront pas toujours des entiers.

Production

La sortie sera un seul mot à STDOUT pour dire si le vaisseau spatial a atterri ou non. Si le navire s'écrase, imprimez crash. Sinon, imprimez escape. Voici la sortie attendue pour l'entrée ci-dessus:

crash

Vous vous demandez peut-être ce qui s'est passé. Voici un article Pastebin qui a un journal de vol détaillé pour le vaisseau spatial. Les chiffres ne sont pas très bons pour aider les gens à visualiser l'événement, alors voici ce qui s'est passé: le vaisseau spatial parvient à échapper à la gravité de la première planète (à l'ouest) à l'aide de la gravité de la deuxième planète (au nord-est). Il se déplace vers le nord puis passe légèrement à l'ouest de la deuxième planète, la manquant à peine. Il se courbe ensuite autour du côté nord de la planète et s'écrase sur le côté est de la deuxième planète.

Quelques cas supplémentaires à examiner

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

échapper (en raison de la loi du carré inverse, 2000 n'est pas beaucoup de gravité si vous êtes à 60 unités)

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

crash (la première planète est extrêmement massive et extrêmement proche)

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

s'échapper (c'est un cas de bord: il n'y a pas de planètes et une interprétation simple suggérerait que le vaisseau spatial est directement au-dessus des planètes)

Règles, restrictions et notes

C'est le golf de code. Les règles de golf à code standard s'appliquent. Votre programme doit être écrit en caractères ASCII imprimables uniquement. Vous ne pouvez accéder à aucune sorte de base de données externe. Vous pouvez écrire des entrées dans n'importe quelle langue (autre qu'une langue spécialisée pour résoudre ce défi).

Fin de transmission

PhiNotPi
la source
rofl DEEEPRAROM! - L'interaction gravitationnelle des planètes n'est pas censée être simulée? Toujours pas exactement cher en termes numériques, mais assez juste. - Je suppose que la simulation de référence utilise l'intégration standard Runge-Kutta 4e ordre, et notre programme doit créer des résultats équivalents?
cessé de tourner dans le sens inverse des aiguilles d'une montre le
Je n'ai pas compris comment faire interagir plusieurs planètes. Le problème est qu'ils auront tendance à se percuter immédiatement. Pour résoudre ce problème, il faudra augmenter considérablement l'échelle de la simulation.
PhiNotPi
Quant à la méthode Runge-Kutta, je ne suis honnêtement pas encore très avancée en mathématiques. :( Ce que j'ai fait était de calculer la gravité à l'emplacement actuel du navire et de l'ajouter à la vitesse du navire, générant la nouvelle vitesse du navire. Je l'ai fait pour chaque pas de temps. Je sais que ce n'est pas complètement précis, mais j'ai découvert que diviser la vitesse de départ du navire et la gravité des planètes par 10 augmente la précision de la simulation.
PhiNotPi
Ah, ce serait la méthode d'Euler. Pour les pas de temps suffisamment petits, celui-ci est également précis; pourtant Runge-Kutta ou quelque chose d'autre plus sophistiqué serait plus intéressant à implémenter IMO. Peut - être que je devrais concevoir mon propre défi, je ne peux pas l' air d'être facilement satis ...
cessais à son tour counterclockwis
@leftaroundabout Allez-y. Vous pouvez faire quelque chose comme "simuler tout le système solaire en utilisant des équations différentielles" ou quelque chose de fantaisiste comme ça, ou peut-être ajouter la troisième dimension.
PhiNotPi

Réponses:

6

Python, 178 170 caractères

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
la source
2
Vous êtes d'humeur complexe aujourd'hui, n'est-ce pas?
cessé de tourner dans le sens inverse des aiguilles d'une montre le
8
oui, isuis ....
Keith Randall
Comment puis-je rivaliser avec ça?
Neil
@Neil: le code ou la plaisanterie pleine d'esprit?
Keith Randall
Et bien le code. La plaisanterie pleine d'esprit que je peux suivre.
Neil
2

Golfrun / GolfScript ?, 243 232 caractères

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 est un langage sur lequel je travaille, né en tant qu'interprète GolfScript C, mais s'est rapidement éloigné d'une manière ou d'une autre; bien que j'aie écrit ce code sans utiliser sciemment des fonctionnalités spécifiques de Golfrun (sauf pour sqrt), le test avec le GolfScript d'origine a échoué (j'ai dû ajouter la fonctionnalité sqrt au code d'origine, je ne suis pas un gourou Ruby mais je crois que le problème est pas mon peaufinage).

Le premier problème avec cette solution est que Golfrun, en tant que GolfScript, n'a pas de calcul en virgule flottante. Il est "simulé" en grossissant les nombres, espérons-le de la bonne manière (mais je ne suis pas sûr à 100% que je l'ai fait de manière cohérente). Même ainsi, la solution ne gère pas les nombres à virgule flottante en entrée, j'ai donc dû les agrandir à la main pour n'avoir que des nombres entiers.

En essayant d'implémenter l'algorithme dans le code Python, j'ai également implémenté des bits de mathématiques complexes d'une manière plutôt "générale". Manipuler l'algorithme pour éviter cela, et / ou l'inclure dans la mesure du possible, retardant les définitions, pourrait sauver d'autres caractères ...

Comment puis-je savoir que ce code fonctionne? En effet, je n'en suis pas sûr! Mais en donnant les exemples en entrée (après avoir "supprimé" les points où ils apparaissent), il a écrit les résultats attendus, à l'exception du "corner case" (qui lève également une exception en Python) ...

ShinTakezou
la source