Code Golf: Uzay gemisinin kaderi nedir? [kayan noktalı sürüm]


12

Bu soru ASCII sanat versiyonundan biraz daha zordur. Sanat yok ve şimdi kayan nokta aritmetiği yapıyorsunuz!

Meydan okuma

USS StackExchange, gemide astronomik bir patlama meydana geldiğinde cg-00DLEF gezegeninin ağırlık alanında ilerliyordu. Geminin baş programlama memuru olarak, cg-00DELF'in güneş sisteminde karaya çarpmak zorunda kalıp kalamayacağınızı tahmin etmek için geminizin yörüngesini simüle etmek sizin görevinizdir. Patlama sırasında geminiz ağır hasar gördü. Uzay gemisinin sınırlı ücretsiz DEEEPRAROM * programı nedeniyle, programınızı mümkün olduğunca az karakterle yazmalısınız.

* Dinamik Olarak Yürütülebilir Elektronik Olarak Silinebilir Programlanabilir Rastgele Erişim Salt Okunur Bellek

Simülasyon

ASCII sanat versiyonu gibi, zaman adımları fikri olacak. Diğer versiyonda, bir zaman adımı nispeten büyük bir süreydi: gemi, bir gezegenin yerçekiminin ötesine tek bir zaman adımında yol alabilirdi. Burada zaman adımı, daha büyük mesafeler nedeniyle çok daha küçük bir zaman birimidir. Bununla birlikte, önemli bir fark, hücrelerin olmamasıdır. Uzay gemisinin mevcut konumu ve hızı, yerçekimi kuvvetleri ile birlikte kayan nokta sayıları olacaktır. Başka bir değişiklik, gezegenlerin artık çok daha büyük bir boyuta sahip olmasıdır.

Simülasyonda en fazla üç gezegen olacak. Üçünün de belirli bir yeri, yarıçapı ve yerçekimi olacaktır. Her gezegenin yerçekimi, doğrudan gezegenin merkezine doğru kuvvet uygulayan bir vektördür. Bu vektörün kuvvetini bulmak için formül (Gravity)/(Distance**2), mesafenin gemiden gezegenin merkezine olan tam mesafedir. Bu, yerçekiminin ulaşabileceği yerde bir sınır olmadığı anlamına gelir.

Belirli bir zamanda, uzay gemisinin bir hızı vardır, bu da son zaman adımından şimdiye kadar kat ettiği mesafe ve açıdır. Geminin de momentumu var. Geçerli zaman adımı ile sonraki adım arasında gideceği mesafe, konumundaki tüm yerçekimi vektörlerine eklenen mevcut hızının toplamıdır. Bu, uzay gemisinin yeni hızı olur.

Her simülasyonun 10000 zaman adımı için bir zaman sınırı vardır. Eğer uzay gemisi bir gezegenin içinde seyahat ederse (gezegenin merkezine gezegenin yarıçapından daha yakınsa), o zaman bu gezegene çarpar. Uzay gemisi simülasyonun sonuna kadar herhangi bir gezegene çarpmazsa, yer çekiminden kaçtığı varsayılır. Geminin o kadar mükemmel bir şekilde hizalanması mümkün değildir, 10001'inci zaman adımında çökerken 10000 zaman adımında yörüngede kalmayı başarır.

Giriş

Giriş, STDIN'e dört satır olacaktır. Her satır dört virgülle ayrılmış sayıdan oluşur. İşte sayıların biçimi:

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

Üçten az gezegen varsa, kalan çizgiler tüm değerler için sıfırlarla doldurulur. İşte bir örnek giriş:

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

Bu, uzay gemisinin (60,0) bulunduğu ve 10 birim / zaman adımında düz "yukarı / kuzey" hareket ettiği anlamına gelir. Biri (0,0) ve diğeri (100,100) 'de bulunan iki gezegen vardır. Her ikisinin ağırlığı 4000 ve yarıçapı 50'dir. Bunların hepsi tamsayı olsa da, her zaman tamsayı olmayacaklardır.

Çıktı

Çıktı, uzay gemisinin çarpışıp inip düşmediğini söylemek için STDOUT'a tek bir kelime olacak. Gemi kazası düşerse, yazdırın crash. Aksi takdirde yazdırın escape. Yukarıdaki giriş için beklenen çıktı:

crash

Ne olduğunu merak ediyor olabilirsiniz. İşte uzay gemisi için ayrıntılı bir uçuş günlüğüne sahip bir Pastebin direği. Sayılar, insanların olayı görselleştirmelerine yardımcı olmakta çok iyi değildir, işte burada olan şey: Uzay gemisi, ilk gezegenin yerçekiminden (batıya) ikinci gezegenin yerçekiminin (kuzeydoğusuna) kaçmasını başarıyor. Kuzeye doğru hareket eder ve sonra ikinci gezegenin batısına hafifçe geçer, ancak onu kaçırır. Daha sonra gezegenin kuzey tarafı etrafında kıvrılır ve ikinci gezegenin doğu tarafına çöker.

Muayene için bazı vakalar

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

kaçış (ters kare yasası nedeniyle, 60 birim uzaktaysanız 2000 çok fazla yerçekimi değildir)

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

çarpışma (ilk gezegen çok büyük ve çok yakın)

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

kaçış (bu bir uç durumdur: gezegen yoktur ve açık bir yorum, uzay gemisinin doğrudan gezegenlerin üstünde olduğunu düşündürür)

Kurallar, Kısıtlamalar ve Notlar

Bu kod golf. Standart kod golf kuralları geçerlidir. Programınız yalnızca yazdırılabilir ASCII karakterleriyle yazılmalıdır. Herhangi bir harici veritabanına erişemezsiniz. Herhangi bir dilde girişler yazabilirsiniz (bu zorluğu çözmek için uzmanlaşmış bir dil dışında).

İletimi Sonlandır


rofl DEEEPRAROM! - Gezegenlerin yerçekimi etkileşimi simüle edilmemeli mi? Hala sayısal olarak tam olarak pahalı değil, ama yeterince adil. - Referans simülasyonun standart Runge-Kutta 4. sıra entegrasyonunu kullandığını ve programımızın eşdeğer sonuçlar yaratması gerektiğini varsayıyorum?
counterclockwis çevirmek için durdu

Birden fazla gezegenin nasıl etkileşime gireceğini anlayamadım. Sorun şu ki, hemen birbirlerine çarpmaya eğilimlidirler. Bunu düzeltmek, simülasyonun ölçeğini inanılmaz derecede yukarı kaldırmayı gerektirecektir.
PhiNotPi

Runge-Kutta yöntemine gelince, dürüst olmak gerekirse henüz matematikte bu kadar gelişmiş değilim. :( Yaptığım şey, geminin mevcut lokasyonundaki yerçekimini hesaplamak ve bunu geminin hızına eklemek, geminin yeni hızını üretmekti.Bunu her adımda yaptım, bunun tamamen doğru olmadığını biliyorum, ama öğrendim o 10 artar simülasyon doğruluğu ile geminin başlangıç hızı ve gezegenin yerçekimi bölünmesi.
PhiNotPi

Ah, bu Euler yöntemi olurdu. Yeterince küçük zaman adımları için de doğrudur; ancak Runge-Kutta veya daha sofistike bir şey IMO'yu uygulamak için daha ilginç olurdu. Belki kendi zorluğumu tasarlamalıyım, kolayca tatmin edilemez gibi görünmüyorum ...
saat yönünün tersine çevirmeyi

@leftaroundabout Devam et. "Diferansiyel denklemleri kullanarak tüm güneş sistemini simüle et" gibi bir şey yapabilir veya böyle süslü bir şey yapabilir veya belki de üçüncü boyuta ekleyebilirsiniz.
PhiNotPi

Yanıtlar:


6

Python, 178170 karakter

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
Bugün karmaşık bir ruh halindesin, değil mi?
counterclockwis'i

8
evet, iam ....
Keith Randall

Bununla nasıl rekabet edebilirim?
Neil

@Neil: kod mu yoksa esprili bir şaka mı?
Keith Randall

Peki kod. Takip edebileceğim esprili şaka.
Neil

2

Golfrun / GolfScript ?, 243 232 karakter

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 üzerinde çalıştığım, GolfScript C tercümanı olarak doğduğum ama yakında bir yere sürüklendiğim bir dildir; Bu kodu bilerek belirli Golfrun özelliklerini kullanmadan yazdım (hariç sqrt), orijinal GolfScript ile test başarısız oldu (orijinal koda sqrt özelliğini eklemek zorunda kaldım, bir Ruby guru değilim ama sorunun olduğuna inanıyorum benim tweaking değil).

Bu çözümün ilk problemi Golfrun'un GolfScript olarak kayan nokta matematiği olmamasıdır. Umarım doğru şekilde rakamları "simüle eder" (ancak tutarlı bir şekilde yaptığımdan% 100 emin değilim). Buna rağmen, çözüm kayan nokta sayılarını girdi olarak işlemez, bu yüzden sadece tamsayı sayılara sahip olmak için bunları elle büyütmek zorunda kaldım.

Algoritmayı Python kodunda uygulamaya çalışırken, karmaşık matematiğin parçalarını oldukça "genel" bir şekilde uyguladım. Bundan kaçınmak için algoritmayı değiştirmek ve / veya mümkün olduğunda satır içi yapmak, tanımları geciktirmek, diğer karakterleri kurtarabilir ...

Bu kodun çalıştığını nasıl bilebilirim? Gerçekten, emin değilim! Ancak örnekleri girdi olarak (göründükleri noktaların "kaldırılmasından" sonra), "köşe davası" (Python'da da bir istisna oluşturan) dışında beklenen sonuçları yazdı ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.