Code Golf: Яка доля космічного корабля? [версія з плаваючою комою]


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

Кінцева передача


rofl DEEEPRAROM! - Гравітаційну взаємодію планет не слід імітувати? Все ще не зовсім дорого чисельно тоді, але досить справедливо. - Я припускаю, що еталонне моделювання використовує стандартну інтеграцію Runge-Kutta 4-го порядку, і наша програма повинна створити рівноцінні результати?
перестали повертати проти годинника,

Я не зрозумів, як зробити взаємодію декількох планет. Проблема полягає в тому, що вони, як правило, негайно врізаться один в одного. Для виправлення цього потрібно неймовірно збільшити масштаб моделювання.
PhiNotPi

Що стосується методу Рунге-Кутти, я, чесно кажучи, ще не такий просунутий у математиці. :( Що я зробив, це обчислити гравітацію на поточному місці судна і додати це до швидкості корабля, генеруючи нову швидкість корабля. Я робив це для кожного кроку часу. Я знаю, що це не зовсім точно, але я дізнався що розділення стартової швидкості корабля і сили тяжкості планет на 10 підвищує точність моделювання.
PhiNotPi

Ах, це був би метод Ейлера. Для досить малих часових кроків, які теж точні; проте Runge-Kutta або щось інше більш складне було б цікавіше реалізувати IMO. Можливо, я повинен придумати свій власний виклик, я не можу бути легко задоволеним ...
перестав повертати зустрічний годинник

@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

Гольфрун - це мова, над якою я працюю, народжений як перекладач GolfScript C, але незабаром відійшов геть; хоча я написав цей код, не використовуючи свідомо конкретних функцій Golfrun (за винятком sqrt), тест з оригінальним GolfScript не вдався (мені довелося додати функцію sqrt до вихідного коду, я не гуру Рубі, але я вважаю, що проблема полягає в не моє налаштування).

Перша проблема цього рішення полягає в тому, що Golfrun, як GolfScript, не має математики з плаваючою комою. Це "імітація" збільшення чисел, сподіваюся, правильним чином (але я не на 100% впевнений, що це зробив цілісно). Тим не менш, рішення не обробляє числа з плаваючою комою як вхідні дані, тому мені довелося збільшувати їх вручну, щоб мати лише цілі числа.

Намагаючись реалізувати алгоритм в коді Python, я також реалізував біти складної математики досить "загальним" способом. Маніпулювання алгоритмом, щоб уникнути цього та / або вкладати, коли це можливо, затягуючи визначення, може врятувати інші символи ...

Як мені знати, що цей код працює? Дійсно, я не впевнений, що це робить! Але, даючи приклади як вхідні дані (після "видалення" точок, де вони з'являються), він записав очікувані результати, за винятком "кутового випадку" (що також викликає виняток у Python) ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.