Code Golf: ¿Cuál es el destino de la nave espacial? [versión de punto flotante]

12

Esta pregunta es un poco más difícil que la versión artística ASCII. ¡No hay arte, y ahora puedes hacer aritmética de coma flotante!

El reto

El USS StackExchange estaba viajando a través del campo de gravedad del planeta cg-00DLEF cuando ocurrió una explosión astronómica a bordo. Como oficial de programación principal de la nave, es su trabajo simular la trayectoria de su nave para predecir si se verá obligado a estrellarse en el sistema solar cg-00DELF. Durante la explosión, su nave sufrió graves daños. Debido al limitado DEEEPRAROM * gratuito de la nave espacial, debe escribir su programa en la menor cantidad de caracteres posible.

* Memoria de solo lectura de acceso aleatorio programable y electrónicamente borrable ejecutable dinámicamente

La simulación

Algo parecido a la versión artística de ASCII, surgirá la idea de los pasos de tiempo. En la otra versión, un paso de tiempo era una cantidad de tiempo relativamente grande: la nave podía viajar mucho más allá de la gravedad de un planeta en un solo paso de tiempo. Aquí, el paso de tiempo es una unidad de tiempo mucho menor debido a las distancias más grandes involucradas. Sin embargo, una diferencia importante es la inexistencia de células. La ubicación y velocidad actuales de la nave espacial serán números de coma flotante, junto con las fuerzas gravitacionales involucradas. Otro cambio es el hecho de que los planetas ahora tienen un tamaño mucho mayor.

Habrá hasta tres planetas en la simulación. Los tres tendrán una ubicación, radio y gravedad específicos. La gravedad de cada planeta es un vector que ejerce una fuerza directamente hacia el centro del planeta. La fórmula para encontrar la fuerza de este vector es (Gravity)/(Distance**2), donde la distancia es la distancia exacta desde la nave hasta el centro del planeta. Esto significa que no hay límite para llegar a la gravedad.

En cualquier momento específico, la nave espacial tiene una velocidad, que es la distancia y el ángulo que recorrió desde el último paso de tiempo hasta ahora. El barco también tiene impulso. La distancia que viajará entre el paso de tiempo actual y el siguiente es la suma de su velocidad actual agregada a todos los vectores de gravedad en su ubicación. Esto se convierte en la nueva velocidad de la nave espacial.

Cada simulación tiene un límite de tiempo de 10000 pasos de tiempo. Si la nave espacial viaja dentro de un planeta (está más cerca del centro del planeta que el radio del planeta), entonces se estrella contra ese planeta. Si la nave espacial no choca contra ningún planeta al final de la simulación, entonces se presume que escapó de la gravedad. Es poco probable que la nave se alinee tan perfectamente que se las arregle para permanecer en órbita durante 10000 pasos de tiempo mientras se estrella en el paso de tiempo 10001.

Entrada

La entrada será de cuatro líneas a STDIN. Cada línea consta de cuatro números delimitados por comas. Aquí está el formato de los números:

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

Si hay menos de tres planetas, las líneas sobrantes se rellenarán con ceros para todos los valores. Aquí hay un ejemplo de entrada:

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

Esto significa que la nave espacial está ubicada en (60,0) y viaja en línea recta "arriba / norte" a una velocidad de 10 unidades / paso de tiempo. Hay dos planetas, uno ubicado en (0,0) y otro en (100,100). Ambos tienen una gravedad de 4000 y un radio de 50. Aunque todos estos son enteros, no siempre serán enteros.

Salida

La salida será una sola palabra para STDOUT para decir si la nave espacial se ha estrellado o no. Si el barco se estrella, imprime crash. De lo contrario, imprimir escape. Aquí está la salida esperada para la entrada anterior:

crash

Quizás te estés preguntando qué pasó. Aquí hay una publicación de Pastebin que tiene un registro de vuelo detallado para la nave espacial. Los números no son muy buenos para ayudar a las personas a visualizar el evento, así que esto es lo que sucedió: la nave espacial logra escapar de la gravedad del primer planeta (hacia el oeste) con la ayuda de la gravedad del segundo planeta (hacia el noreste). Se mueve hacia el norte y luego pasa ligeramente hacia el oeste del segundo planeta, apenas lo pierde. Luego se curva alrededor del lado norte del planeta y se estrella contra el lado este del segundo planeta.

Algunos casos más para examen

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

escape (debido a la ley del cuadrado inverso, 2000 no es mucha gravedad si estás a 60 unidades de distancia)

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

accidente (el primer planeta es extremadamente masivo y extremadamente cercano)

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

escape (este es un caso extremo: no hay planetas y una interpretación directa sugeriría que la nave espacial está directamente encima de los planetas)

Reglas, restricciones y notas

Este es el código de golf. Se aplican las reglas estándar del código de golf. Su programa debe escribirse solo en caracteres ASCII imprimibles. No puede acceder a ningún tipo de base de datos externa. Puede escribir entradas en cualquier idioma (que no sea uno especializado para resolver este desafío).

Fin de transmisión

PhiNotPi
fuente
rofl DEEEPRAROM! - ¿No se supone que la interacción gravitacional de los planetas sea simulada? Todavía no es exactamente caro numéricamente, pero lo suficientemente justo. - Supongo que la simulación de referencia utiliza la integración estándar de cuarto orden Runge-Kutta, ¿y nuestro programa debe crear resultados equivalentes?
dejó de girar en contra del reloj el
No he descubierto cómo interactuar con varios planetas. El problema es que tenderán a chocar entre sí de inmediato. Arreglar esto requerirá aumentar la escala de la simulación increíblemente.
PhiNotPi
En cuanto al método Runge-Kutta, honestamente todavía no estoy tan avanzado en matemáticas. :( Lo que hice fue calcular la gravedad en la ubicación actual de la nave y agregar esto a la velocidad de la nave, generando la nueva velocidad de la nave. Lo hice para cada paso de tiempo. Sé que esto no es completamente exacto, pero descubrí que dividir la velocidad de inicio del barco y la gravedad de los planetas por 10 aumenta la precisión de la simulación
PhiNotPi
Ah, ese sería el método de Euler. Para pasos de tiempo lo suficientemente pequeños, uno también es preciso; Sin embargo, Runge-Kutta o algo más sofisticado sería más interesante para implementar IMO. Tal vez debería diseñar mi propio desafío, me parece que no puede ser fácilmente satisfiable ...
dejó de turno counterclockwis
@leftaroundabout Adelante. Puede hacer algo como "simular todo el sistema solar usando ecuaciones diferenciales" o algo elegante como eso, o tal vez agregar la tercera dimensión.
PhiNotPi

Respuestas:

6

Python, 178 170 caracteres

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
fuente
2
Estás de un humor complejo hoy, ¿verdad?
dejó de girar en contra del reloj el
8
sí, isoy ...
Keith Randall
¿Cómo puedo competir con eso?
Neil
@Neil: ¿el código o las bromas ingeniosas?
Keith Randall el
Pues el código. Las bromas ingeniosas con las que puedo seguir el ritmo.
Neil
2

Golfrun / GolfScript? 243 232 caracteres

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 es un lenguaje en el que estoy trabajando, nacido como intérprete de GolfScript C, pero pronto se alejó de alguna manera; aunque he escrito este código sin utilizar funciones Golfrun específicas a sabiendas (a excepción de sqrt), la prueba con el GolfScript original falló (tuve que agregar la función sqrt al código original, no soy un gurú de Ruby pero creo que el problema es No es mi ajuste).

El primer problema con esta solución es que Golfrun, como GolfScript, no tiene matemática de coma flotante. Se "simula" ampliando los números, con suerte de la manera correcta (pero no estoy 100% seguro de haberlo hecho de manera coherente). Aun así, la solución no maneja números de punto flotante como entrada, por lo que tuve que ampliarlos a mano para tener solo números enteros.

Intentando implementar el algoritmo en el código de Python, también he implementado bits de matemática compleja de una manera bastante "general". Manipular el algoritmo para evitar esto, y / o incluir siempre que sea posible, retrasar las definiciones, podría salvar otros caracteres ...

¿Cómo sé que funciona este código? De hecho, no estoy seguro de que lo haga. Pero dando los ejemplos como entrada (después de "eliminar" los puntos donde aparecen), escribió los resultados esperados, excepto por el "caso de la esquina" (que también plantea una excepción en Python) ...

ShinTakezou
fuente