Code Golf: Qual è il destino dell'astronave? [Versione ASCII art]


14

sfondo

In una galassia (e forse un universo) molto, molto lontano ... c'erano un'astronave e un gruppo di pianeti. Un malfunzionamento a bordo ha fatto sì che l'astronave rimanesse senza carburante. Ora si sta muovendo a una velocità pericolosamente lenta vicino a un gruppo di pianeti, da cui deve fuggire! Quale sarà il destino dell'equipaggio?

La sfida

Sei il programmatore principale su USS StackExchange. Come tale, desideri scrivere un simulatore che rivelerà se sei condannato o meno a schiantare una terra su un pianeta, sfuggire al sistema planetario o rimanere bloccato in orbita per sempre.

L'esplosione sulla tua astronave, tuttavia, significa che c'erano risorse di calcolo molto limitate. Il tuo programma deve essere il più piccolo possibile. Inoltre, ciò significa che l'unico modo possibile per introdurre simulazioni da eseguire è attraverso l'arte ASCII.

La simulazione

In questo quadrante del multiverso, le leggi della fisica sono leggermente modificate per adattarsi all'arte ASCII. Ciò significa che il cosmo è diviso in cellule. Il movimento sarà descritto in unità di celle e il tempo sarà in unità di fasi temporali.

La nave stessa ha slancio. Se la nave ha spostato +2 celle sull'asse x e -1 cella sull'asse y (abbreviata come (2, -1)) nella fase temporale precedente e non esiste un campo gravitazionale, la nave si sposterà con l'esatto stessa velocità nella fase successiva.

Ci saranno diversi pianeti, ognuno dei quali eserciterà un campo gravitazionale sulle otto celle che lo circondano immediatamente, il che influenzerà la velocità della nave e la avvicinerà al pianeta. Essere appena "a nord" di un pianeta comporterà un campo che tira la nave di una cella a "sud" con una forza di (-1,0). Essere solo "nord-est" di un pianeta comporterà una forza che tira la nave di una cella a "sud" e di un'unità a "ovest" con una forza di (-1, -1).

I campi gravitazionali aggiungono un vettore allo slancio della nave mentre lascia la cellula con la gravità. Se una nave ha appena spostato (2, -1) celle e ora si trova in un campo gravitazionale di (-1,1), in questa fase successiva sposta (1,0) celle. Se la nave si trova nelle immediate vicinanze di più pianeti, allora ci saranno più vettori da aggiungere.

Ingresso

Su STDIN, riceverai una rappresentazione in arte ASCII del sistema planetario che mostrerà le coordinate dei pianeti e la velocità attuale della tua nave. Ci saranno diversi pianeti sotto forma di segni @, mentre ci sarà un'astronave sotto forma di segno av ^ <>. La scelta del simbolo per la nave indica la velocità corrente della nave (prima che sia stata aggiunta la gravità). Ad esempio, a <indica una velocità di una cella verso ovest, mentre a ^ indica una velocità di una cella verso nord. Tutto lo spazio vuoto sarà costituito da punti, che riempiono ogni riga della stessa larghezza. Una riga vuota rappresenta la fine dell'input. Ecco un esempio di input:

.................
...@.@........v..
......@..@..@@...
..@..............
.......@..@......
.................

Produzione

L'output sarà una sola parola su STDOUT, che indicherà se la nave sfuggirà alla gravità, si schianterà contro un pianeta o orbiterà per sempre.

La fuga dalla gravità è definita come la nave che si sposta dalla mappa. Se la nave fugge, il tuo programma deve stampare la parola "fuga".

Lo sbarco si verifica quando una nave passa direttamente su un pianeta o finisce nella stessa cella durante una fase temporale. Si noti che non è sufficiente calcolare semplicemente dove si trova la nave ogni volta che si passa. Una nave che si muove a una velocità di (5,5) si schianterà contro un pianeta situato a (1,1) anche se un semplice calcolo significherà che non visiterà mai quella cella. Tuttavia, una nave con una velocità di (5,6) non si schianterà contro il pianeta. Se il crash della tua astronave si interrompe, il tuo programma deve stampare la parola "crash".

L'orbita può essere la più difficile da rilevare. L'orbita si verifica ogni volta che l'astronave visita la stessa cella due volte e con la stessa velocità. Se la nave orbita, allora dovresti stampare la parola "orbita".

Ecco l'output per l'esempio sopra:

escape

Spiegazione

Ecco una mappa che mostra dove l'astronave ha viaggiato in ogni passaggio temporale nell'esempio sopra:

   ^
.................
...@.@........v..
....^.@..@..@@...
..@..<.<<<.<.v...
.......@..@......
.................

Andò a sud, si voltò a ovest, percorse un corridoio, si voltò a nord e fuggì per poco tra i pianeti ad alta velocità, tutti a causa della gravità.


Più casi da esaminare

...
^@.
...
orbit
...........
.>@.@......
.@......@..
....@......
crash (it crashes into the easternmost planet)
...
.@.
.v.
crash (momentum can't overcome gravity)
........
..@.....
..<.....
...@....
........
orbit (it gets trapped in a gravity well between two planets)

Regole, regolamenti e note

Questo è il codice golf. Si applicano le regole standard per il golf. I tuoi programmi devono essere scritti in ASCII stampabile. Non è consentito accedere a nessun tipo di database esterno.

Termina trasmissione


Sembra che ci sia un refuso nella riga appena sopra la sezione INPUT ... Presumo che tu intenda il pianeta? :-)
Gaffi

In realtà, è necessario eliminare l'intero paragrafo parziale, le informazioni vengono ripetute nella sezione di output.
PhiNotPi

1
Mi piacerebbe di più con una fisica leggermente meno alterata ... questo sito potrebbe fare con più problemi che comportano anche un po 'di costosa aritmetica in virgola mobile.
cessò di girare in senso antiorario il

1
@leftaroundabout Potrebbe essere la mia prossima sfida.
PhiNotPi

Quanto vicino a un pianeta deve essere necessario per schiantarsi contro di esso?
Peter Taylor,

Risposte:


6

C # 991 984

struct P{public P(int x,int y){X=x;Y=y;}public int X,Y;}
class O:Exception{}
class C:O{}
List<P>p=new List<P>();
List<string>h=new List<string>();
P r,v,u;
void S(){
var i=0;
for(var l=Console.ReadLine();l!="";l=Console.ReadLine())
{u.X=l.Select((c,j)=>
{if(c=='@')p.Add(new P(j,i));else if(c!='.')
{r=new P(j,i);v=(c=='v'?new P(0,1):c=='<'?new P(-1,0):c=='^'?new P(0,-1):new P(1,0));}
return u;}).Count();i++;}
u.Y=i;
var x=new Action<string>(Console.WriteLine);
try{
while(true){
p.ForEach(q=>{var a=q.X-r.X;var b=q.Y-r.Y;
if(a<2&&a>-2&&b<2&&b>-2){v.X+=a;v.Y+=b;}});
var c=string.Join(".",r.X,r.Y,v.X,v.Y);
if(h.Contains(c))throw new O();
h.Add(c);
var z=new P(r.X,r.Y);var k=new[]{v.X,v.Y};var m=k.Min();var M=k.Max();
for(var j=1;j<=M;j++)
if((j*m)%M==0){
if(p.Contains(new P(z.X+(v.X==M?j:j*m/M),z.Y+(v.Y==M?j:j*m/M))))throw new C();}
r.X+=v.X;r.Y+=v.Y;
if(r.X<0||r.X>=u.X||r.Y<0||r.Y>=u.Y)throw new Exception();}}
catch(C){x("crush");}
catch(O){x("orbit");}
catch{x("escape");}}

La versione ungolf (e leggermente refactored) è disponibile su http://pastebin.com/yAKYvwQf

Versione in esecuzione: https://compilify.net/1n9 Questo è stato leggermente modificato per essere eseguito su complify:

  • nessuna creazione implicita di array - es: new[]{1,2}
  • usa return <string>invece di Console.WriteLine, perché è così che funziona compilify.net
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.