Code Golf: Jaki jest los statku kosmicznego? [wersja zmiennoprzecinkowa]

12

To pytanie jest nieco trudniejsze niż wersja artystyczna ASCII. Nie ma sztuki, a teraz możesz wykonać arytmetykę zmiennoprzecinkową!

Wyzwanie

USS StackExchange podróżował przez pole grawitacyjne planety cg-00DLEF, kiedy na pokładzie miała miejsce eksplozja astronomiczna. Jako główny programista statku, Twoim zadaniem jest symulacja trajektorii statku, aby przewidzieć, czy będziesz zmuszony rozbić ląd w układzie słonecznym cg-00DELF. Podczas wybuchu twój statek został poważnie uszkodzony. Z powodu ograniczonej bezpłatnej DEEEPRAROM * statku kosmicznego, musisz napisać swój program w jak najmniejszej liczbie znaków.

* Dynamicznie wykonywalna elektronicznie kasowalna programowalna pamięć o dostępie swobodnym tylko do odczytu

Symulacja

W pewnym sensie, podobnie jak w przypadku wersji ASCII, pojawią się pomiary czasu. W drugiej wersji krok czasowy był stosunkowo długi: statek mógł podróżować daleko poza grawitację planety w jednym kroku czasowym. Tutaj krok czasowy jest znacznie mniejszą jednostką czasu ze względu na większe odległości. Jedną z głównych różnic jest jednak brak komórek. Obecne położenie i prędkość statku kosmicznego będą liczbami zmiennoprzecinkowymi, wraz z zaangażowanymi siłami grawitacyjnymi. Kolejną zmianą jest fakt, że planety mają teraz znacznie większy rozmiar.

W symulacji będą maksymalnie trzy planety. Wszystkie trzy będą miały określoną lokalizację, promień i grawitację. Grawitacja każdej planety jest wektorem, który wywiera siłę bezpośrednio w kierunku środka planety. Wzór na znalezienie siły tego wektora jest taki (Gravity)/(Distance**2), gdzie odległość jest dokładną odległością statku od centrum planety. Oznacza to, że nie ma ograniczeń co do zasięgu grawitacji.

W dowolnym momencie statek kosmiczny ma prędkość, która jest odległością i kątem, jaki przebył od ostatniego kroku czasu do teraz. Statek ma również rozpęd. Odległość, którą pokona między bieżącym krokiem czasowym a następnym, jest sumą jego prędkości prądu dodanej do wszystkich wektorów grawitacyjnych w jego położeniu. To staje się nową prędkością statku kosmicznego.

Każda symulacja ma limit czasowy 10000 kroków czasowych. Jeśli statek kosmiczny podróżuje wewnątrz planety (znajduje się bliżej środka planety niż w promieniu planety), wówczas zderza się z tą planetą. Jeśli statek kosmiczny nie uderzy w żadną planetę przed końcem symulacji, zakłada się, że uciekł przed grawitacją. Jest mało prawdopodobne, aby statek mógł być ustawiony tak idealnie, że uda mu się pozostać na orbicie przez 10000 kroków czasowych podczas awarii na 10001 kroku czasowym.

Wejście

Wprowadzane będą cztery wiersze do STDIN. Każda linia składa się z czterech liczb rozdzielanych przecinkami. Oto format liczb:

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

Jeśli jest mniej niż trzy planety, wówczas pozostałe linie zostaną wypełnione zerami dla wszystkich wartości. Oto przykładowe dane wejściowe:

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

Oznacza to, że statek kosmiczny znajduje się w (60,0) i leci prosto „w górę / na północ” z prędkością 10 jednostek / krok czasowy. Istnieją dwie planety, jedna znajduje się w (0,0), a druga w (100,100). Oba mają grawitację 4000 i promień 50. Mimo że wszystkie są liczbami całkowitymi, nie zawsze będą liczbami całkowitymi.

Wynik

Wyjście będzie pojedynczym słowem dla STDOUT, informującym, czy statek kosmiczny wylądował, czy nie. Jeśli katastrofa statku wyląduje, wydrukuj crash. W przeciwnym razie wydrukuj escape. Oto oczekiwany wynik dla powyższego wejścia:

crash

Być może zastanawiasz się, co się stało. Oto post Pastebin ze szczegółowym dziennikiem lotów dla statku kosmicznego. Liczby nie są zbyt dobre w pomaganiu ludziom w wizualizacji zdarzenia, więc oto co się stało: statkowi kosmicznemu udaje się uciec grawitacji pierwszej planety (na zachodzie) za pomocą grawitacji drugiej planety (na północnym wschodzie). Porusza się na północ, a następnie przechodzi nieznacznie na zachód od drugiej planety, ledwo ją omijając. Następnie zakręca wokół północnej strony planety i uderza we wschodnią stronę drugiej planety.

Jeszcze kilka przypadków do zbadania

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

ucieczka (ze względu na odwrotne prawo do kwadratu, 2000 nie ma dużej grawitacji, jeśli jesteś w odległości 60 jednostek)

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

katastrofa (pierwsza planeta jest niezwykle masywna i bardzo blisko)

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

ucieczka (jest to przypadek skrajny: nie ma planet, a prosta interpretacja sugerowałaby, że statek kosmiczny znajduje się bezpośrednio nad planetami)

Reguły, ograniczenia i uwagi

To jest kod golfowy. Obowiązują standardowe zasady gry w golfa. Twój program powinien być napisany tylko drukowalnymi znakami ASCII. Nie możesz uzyskać dostępu do żadnej zewnętrznej bazy danych. Możesz pisać wpisy w dowolnym języku (innym niż ten, który specjalizuje się w rozwiązywaniu tego problemu).

Zakończ transmisję

PhiNotPi
źródło
rofl DEEEPRAROM! - Czy oddziaływanie grawitacyjne planet nie powinno być symulowane? Wciąż nie dość drogie liczbowo, ale dość uczciwe. - Zakładam, że symulacja referencyjna wykorzystuje standardową integrację czwartego rzędu Runge-Kutta, a nasz program musi tworzyć równoważne wyniki?
przestał się obracać w lewo o
Nie wymyśliłem, jak robić interakcje wielu planet. Problem polega na tym, że mają tendencję do natychmiastowego zderzania się ze sobą. Naprawienie tego będzie wymagało niesamowitego zwiększenia skali symulacji.
PhiNotPi
Jeśli chodzi o metodę Runge-Kutty, to nie jestem jeszcze tak zaawansowany w matematyce. :( Zrobiłem to, aby obliczyć grawitację w bieżącej lokalizacji statku i dodać to do prędkości statku, generując nową prędkość statku. Zrobiłem to dla każdego kroku. Wiem, że nie jest to całkowicie dokładne, ale dowiedziałem się dzielenie prędkości początkowej statku i grawitacji planet przez 10 zwiększa dokładność symulacji.
PhiNotPi
Ach, to byłaby metoda Eulera. W przypadku wystarczająco małych kroków czasowych również jeden jest dokładny; jednak Runge-Kutta lub coś bardziej wyrafinowanego byłoby ciekawsze do wdrożenia IMO. Może powinienem wymyślić własne wyzwanie, nie wydaje mi się, aby być łatwo satysfakcjonującym ...
przestałem obracać przeciwnie do zegara
@leftaroundabout Śmiało. Możesz zrobić coś w rodzaju „symulacji całego układu słonecznego za pomocą równań różniczkowych” lub czegoś takiego wymyślnego, a może dodać w trzecim wymiarze.
PhiNotPi

Odpowiedzi:

6

Python, 178 170 znaków

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
źródło
2
Jesteś dziś w złożonym nastroju, prawda?
przestał obracać przeciwnie do zegara
8
tak, ijestem ....
Keith Randall,
Jak mogę z tym konkurować?
Neil,
@Neil: kod, czy dowcipny żart?
Keith Randall,
Cóż, kod. Dowcipne przekomarzanie się mogę nadążyć.
Neil,
2

Golfrun / GolfScript ?, 243 232 znaki

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 to język, nad którym pracuję, urodzony jako tłumacz języka GolfScript C, ale wkrótce jakoś odpłynął; chociaż napisałem ten kod bez użycia świadomie określonych funkcji Golfrun (z wyjątkiem sqrt), test z oryginalnym GolfScript nie powiódł się (musiałem dodać funkcję sqrt do oryginalnego kodu, nie jestem guru Ruby, ale wierzę, że problem jest nie moje poprawki).

Pierwszym problemem związanym z tym rozwiązaniem jest to, że Golfrun jako GolfScript nie ma matematyki zmiennoprzecinkowej. Jest to „symulowane” powiększanie liczb, mam nadzieję, że we właściwy sposób (ale nie jestem w 100% pewien, że zrobiłem to spójnie). Mimo to rozwiązanie nie obsługuje liczb zmiennoprzecinkowych jako danych wejściowych, więc musiałem je powiększyć ręcznie, aby miały tylko liczby całkowite.

Próbując zaimplementować algorytm w kodzie Pythona, zaimplementowałem również fragmenty złożonej matematyki w dość „ogólny” sposób. Manipulowanie algorytmem w celu uniknięcia tego i / lub wstawianie, gdy tylko jest to możliwe, opóźnianie definicji, mogłoby zapisać inne znaki ...

Skąd mam wiedzieć, że ten kod działa? Rzeczywiście, nie jestem pewien, czy tak! Ale podając przykłady jako dane wejściowe (po „usunięciu” punktów, w których się pojawiają), napisał oczekiwane wyniki, z wyjątkiem „przypadku narożnika” (który podnosi wyjątek również w Pythonie) ...

ShinTakezou
źródło