Код Гольф: какова судьба космического корабля? [версия с плавающей запятой]

12

Этот вопрос немного сложнее, чем художественная версия ASCII. Там нет искусства, и теперь вы можете сделать некоторую арифметику с плавающей запятой!

Соревнование

USS StackExchange путешествовал через гравитационное поле планеты cg-00DLEF, когда на борту произошел астрономический взрыв. Как главный специалист по программированию корабля, ваша задача - моделировать траекторию вашего корабля, чтобы предсказать, будете ли вы вынуждены терпеть крушение на суше в солнечной системе cg-00DELF. Во время взрыва ваш корабль был сильно поврежден. Из-за ограниченного свободного DEEEPRAROM * космического корабля, вы должны написать свою программу как можно меньше символов.

* Динамически исполняемая электронно стираемая программируемая оперативная память только для чтения

Симуляция

Что-то вроде художественной версии ASCII, будет идея временных шагов. В другой версии временной шаг был относительно большим количеством времени: корабль мог путешествовать далеко за пределы гравитации планеты за один временной шаг. Здесь временной шаг - намного меньшая единица времени из-за больших вовлеченных расстояний. Однако одно из основных отличий заключается в отсутствии клеток. Текущее местоположение и скорость космического корабля будут числами с плавающей точкой, наряду с вовлеченными гравитационными силами. Другое изменение заключается в том, что планеты теперь имеют гораздо больший размер.

В симуляции будет до трех планет. Все три будут иметь определенное местоположение, радиус и гравитацию. Гравитация для каждой планеты - это вектор, который прилагает силу непосредственно к центру планеты. Формула для определения силы этого вектора: (Gravity)/(Distance**2)где расстояние - это точное расстояние от корабля до центра планеты. Это означает, что нет предела, где гравитация может достигать.

В любое конкретное время космический корабль имеет скорость, которая является расстоянием и углом, который он прошел от последнего временного шага до настоящего времени. Корабль также имеет импульс. Расстояние, которое он пройдет между текущим временным шагом и следующим, является суммой его текущей скорости, добавленной ко всем векторам гравитации в его местоположении. Это становится новой скоростью космического корабля.

Каждое моделирование имеет ограничение по времени 10000 временных шагов. Если космический корабль путешествует внутри планеты (он находится ближе к центру планеты, чем радиус планеты), то он врезается в эту планету. Если космический корабль не врезается в какую-либо планету к концу симуляции, то предполагается, что он сбежал из гравитации. Маловероятно, что корабль может быть выровнен настолько идеально, что ему удастся остаться на орбите в течение 10000 временных шагов, в то же время потерпев крушение на 10001-м временном шаге.

вход

Ввод будет четыре строки для 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

побег (из-за закона обратных квадратов, 2000 не так много гравитации, если вы на расстоянии 60 единиц)

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. Вы не можете получить доступ к какой-либо внешней базе данных. Вы можете писать записи на любом языке (кроме того, который специализируется на решении этой задачи).

Конец передачи

PhiNotPi
источник
rofl DEEEPRAROM! - Гравитационное взаимодействие планет не должно моделироваться? Тогда все еще не слишком дорого, но достаточно справедливо. - Я полагаю, что при эталонном моделировании используется стандартная интеграция Рунге-Кутты 4-го порядка, и наша программа должна создавать эквивалентные результаты?
перестал поворачивать против часовой стрелки
Я не понял, как взаимодействовать между несколькими планетами. Проблема в том, что они сразу же будут сталкиваться друг с другом. Исправление этого потребует невероятного увеличения масштаба симуляции.
PhiNotPi
Что касается метода Рунге-Кутты, я, честно говоря, еще не настолько продвинут в математике. :( То, что я сделал, было рассчитать гравитацию в текущем местоположении корабля и добавить это к скорости корабля, генерируя новую скорость корабля. Я делал это для каждого временного шага. Я знаю, что это не совсем точно, но я выяснил, что деление начальной скорости корабля и силы тяжести планет на 10 повышает точность моделирования
PhiNotPi
Ах, это был бы метод Эйлера. Для достаточно малых временных шагов это тоже точно; все же Рунге-Кутта или что-то еще более изощренное было бы более интересным для внедрения ИМО. Может быть, я должен разработать свой собственный вызов, я не могу казаться легко выполнимым ...
перестал поворачиваться против часовой стрелки
@leftaroundabout Давай. Вы можете сделать что-то вроде «имитировать всю солнечную систему с помощью дифференциальных уравнений» или что-то подобное, или, возможно, добавить в третье измерение.
PhiNotPi

Ответы:

6

Питон, 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
У тебя сегодня сложное настроение?
перестал поворачиваться против часовой стрелки с
8
да, iя ....
Кит Рэндалл
Как я могу соревноваться с этим?
Нил
@Neil: код или остроумный стеб?
Кит Рэндалл
Ну код. Остроумный стеб, с которым я могу не отставать.
Нил
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, я также реализовал немного сложной математики довольно «общим» способом. Манипулирование алгоритмом, чтобы избежать этого, и / или вставка по возможности, задерживая определения, могут сохранить другие символы ...

Как я знаю, что этот код работает? На самом деле, я не уверен, что это так! Но предоставляя примеры в качестве входных данных (после «удаления» точек, где они появляются), он записал ожидаемые результаты, за исключением «углового случая» (который также вызывает исключение в Python) ...

ShinTakezou
источник