Code Golf: Was ist das Schicksal des Raumschiffs? [ASCII-Kunstversion]


14

Hintergrund

In einer Galaxie (und möglicherweise einem Universum) weit, weit weg ... gab es ein Raumschiff und ein paar Planeten. Durch eine Störung an Bord ging dem Raumschiff der Treibstoff aus. Es bewegt sich jetzt mit einer gefährlich langsamen Geschwindigkeit in der Nähe einer Gruppe von Planeten, von denen es entkommen muss! Was wird das Schicksal der Crew sein?

Die Herausforderung

Sie sind der führende Programmierer auf der USS StackExchange. Als solches möchten Sie einen Simulator schreiben, der aufzeigt, ob Sie dazu verdammt sind, auf einem Planeten zu landen, dem Planetensystem zu entkommen oder für immer im Orbit festsitzen.

Die Explosion in Ihrem Raumschiff bedeutet jedoch, dass nur sehr begrenzte Rechenressourcen zur Verfügung standen. Ihr Programm muss so klein wie möglich sein. Dies bedeutet auch, dass die einzige Möglichkeit zur Eingabe von auszuführenden Simulationen ASCII-Kunst ist.

Die Simulation

In diesem Quadranten des Multiversums werden die Gesetze der Physik geringfügig geändert, um der ASCII-Kunst Rechnung zu tragen. Dies bedeutet, dass der Kosmos in Zellen aufgeteilt ist. Die Bewegung wird in Einheiten von Zellen beschrieben, und die Zeit wird in Einheiten von Zeitschritten angegeben.

Das Schiff selbst hat Schwung. Wenn das Schiff im vorherigen Zeitschritt +2 Zellen auf der x-Achse und -1 Zelle auf der y-Achse (Kurzform als (2, -1)) bewegt hat und es kein Gravitationsfeld gibt, bewegt sich das Schiff mit der exakten gleiche Geschwindigkeit beim nächsten Zeitschritt.

Es wird mehrere Planeten geben, die alle ein Gravitationsfeld auf die acht sie unmittelbar umgebenden Zellen ausüben, was die Schiffsgeschwindigkeit beeinflusst und das Schiff näher an den Planeten heranzieht. Nur "nördlich" von einem Planeten zu sein, wird dazu führen, dass ein Feld das Schiff mit einer Kraft von (-1,0) eine Zelle nach "Süden" zieht. Nur "nordöstlich" von einem Planeten zu sein, wird dazu führen, dass das Schiff mit einer Kraft von (-1, -1) eine Zelle nach "Süden" und eine Einheit nach "Westen" gezogen wird.

Die Gravitationsfelder fügen dem Impuls des Schiffes einen Vektor hinzu, wenn es die Zelle mit der Schwerkraft verlässt. Wenn ein Schiff gerade zuvor (2, -1) Zellen bewegt hat und sich jetzt in einem Gravitationsfeld von (-1,1) befindet, bewegt es in diesem nächsten Zeitschritt (1,0) Zellen. Befindet sich das Schiff in unmittelbarer Nähe mehrerer Planeten, müssen mehrere Vektoren hinzugefügt werden.

Eingang

Auf STDIN erhalten Sie eine ASCII-Grafik des Planetensystems, die die Koordinaten der Planeten und die aktuelle Geschwindigkeit Ihres Schiffes anzeigt. Es wird mehrere Planeten in Form von @ -Zeichen geben, während es ein Raumschiff in Form von av ^ <> -Zeichen geben wird. Die Auswahl des Symbols für das Schiff gibt die aktuelle Geschwindigkeit des Schiffes an (bevor die Schwerkraft hinzugefügt wurde). Zum Beispiel bedeutet a <eine Geschwindigkeit von einer Zelle nach Westen, während a ^ eine Geschwindigkeit von einer Zelle nach Norden bedeutet. Der gesamte leere Raum besteht aus Punkten, die jede Zeile mit der gleichen Breite auffüllen. Eine leere Zeile steht für das Ende der Eingabe. Hier ist ein Beispiel für eine Eingabe:

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

Ausgabe

Die Ausgabe wird ein einzelnes Wort auf STDOUT sein, das angibt, ob das Schiff der Schwerkraft entkommt, auf einem Planeten landet oder für immer umkreist.

Das Entkommen aus der Schwerkraft ist definiert als das Schiff, das sich von der Karte entfernt. Wenn das Schiff entkommt, muss Ihr Programm das Wort "escape" ausgeben.

Eine Bruchlandung ist, wenn ein Schiff direkt über einen Planeten fährt oder während eines Zeitschritts in derselben Zelle landet. Beachten Sie, dass es nicht ausreicht, bei jedem Zeitschritt einfach zu berechnen, wo sich das Schiff befindet. Ein Schiff, das sich mit einer Geschwindigkeit von (5,5) bewegt, stürzt auf einen Planeten ab, der sich bei (1,1) befindet, obwohl eine einfache Berechnung bedeutet, dass es diese Zelle niemals besuchen wird. Ein Schiff mit einer Geschwindigkeit von (5,6) landet jedoch nicht auf dem Planeten. Wenn Ihr Raumschiff abstürzt, muss Ihr Programm das Wort "crash" ausgeben.

Die Umlaufbahn ist möglicherweise am schwierigsten zu erkennen. Die Umlaufbahn entsteht immer dann, wenn das Raumschiff dieselbe Zelle zweimal und mit derselben Geschwindigkeit besucht. Wenn das Schiff umkreist, sollten Sie das Wort "Umlaufbahn" drucken.

Hier ist die Ausgabe für das obige Beispiel:

escape

Erläuterung

Hier ist eine Karte, die zeigt, wohin das Raumschiff in jedem Zeitschritt im obigen Beispiel gefahren ist:

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

Es ging nach Süden, wandte sich nach Westen, ging einen Korridor hinunter, wandte sich nach Norden und floh mit hoher Geschwindigkeit, alles wegen der Schwerkraft, knapp auf Planeten zu.


Weitere Fälle zur Prüfung

...
^@.
...
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)

Regeln, Vorschriften und Hinweise

Das ist Code Golf. Es gelten die Standard-Code-Golfregeln. Ihre Programme müssen in druckbarem ASCII geschrieben sein. Sie dürfen nicht auf irgendeine Art von externer Datenbank zugreifen.

Übertragung beenden


Es scheint einen Tippfehler in der Zeile über dem INPUT-Bereich zu geben ... Ich nehme an, Sie meinen den Planeten? :-)
Gaffi

Eigentlich musste dieser ganze Teilabsatz gelöscht werden, die Informationen werden unter dem Ausgabeabschnitt wiederholt.
PhiNotPi

1
Ich hätte das gerne besser mit etwas weniger veränderter Physik ... diese Seite könnte mehr Probleme mit sich bringen, die auch ein wenig teure Gleitkomma-Arithmetik mit sich bringen.
drehte sich nicht mehr gegen den Uhrzeigersinn am

1
@leftaroundabout Das könnte meine nächste Herausforderung sein.
PhiNotPi

Wie nah muss es an einem Planeten sein, um darauf zu stoßen?
Peter Taylor

Antworten:


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");}}

Die ungolfed (und leicht überarbeitete) Version ist unter http://pastebin.com/yAKYvwQf verfügbar

Laufende Version: https://compilify.net/1n9 Dies wurde leicht modifiziert, um ausgeführt zu werden auf:

  • Keine implizite Array-Erstellung - Beispiel: new[]{1,2}
  • verwendet return <string>statt Console.WriteLine, denn so funktioniert compilify.net
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.