Aircraft Marshalling School

8

Schreiben Sie eine Funktion oder ein Programm, um die endgültige Position eines Flugzeugs nach diesen Signalen zu berechnen, wenn eine Zeichenfolge eine Reihe von Handzeichen für das Rangieren von Flugzeugen darstellt.

NB: Die Koordinaten in dieser Herausforderung sind als ein Paar kartesischer Koordinaten dargestellt wird , sowie eine Kompassrichtung heading: (x, y, h)wo xist die x-Koordinate, ydie Y-Koordinate, und heines von N, E, Soder W.

Sie starten mit einem Flugzeug in (0, 0, N)einem imaginären Raster, bei ausgeschaltetem Motor. Ihre Eingabe ist eine Zeichenfolge, die durch Kommas getrennte Zeichenpaare enthält, wobei jedes Paar ein Marshalling-Signal darstellt. Sie müssen nacheinander jedem Rangiersignal folgen und die Koordinaten in (x, y, h)Form der Endposition des Flugzeugs ausgeben .

Wenn ein Signal erfordert, dass sich Ihr Flugzeug bewegt, nehmen Sie an, dass es für jedes Signal dieses Typs, das es empfängt, eine Einheit in die erforderliche Richtung bewegt . Wenn ein Signal erfordert, dass sich Ihr Flugzeug dreht, nehmen Sie an, dass es sich für jedes Signal dieses Typs, das es empfängt, um 90 Grad in die erforderliche Richtung dreht.

Ein Flugzeug kann sich nicht bewegen, wenn die Triebwerke ausgeschaltet sind. Wenn die Triebwerke Ihres Flugzeugs ausgeschaltet sind und Sie einen Bewegungs- / Blinker erhalten, wenden Sie die Bewegung / Drehung nicht an.

Signale

Jedes Rangiersignal wird durch ein Zeichenpaar dargestellt. Der erste des Paares repräsentiert die Position des linken Arms des Marshallers aus Sicht des Flugzeugs und der zweite den rechten Arm aus derselben POV. Diese handliche Signalübersicht kann hilfreich sein.

o/  —  START ENGINES (no movement, no turn)
-/  —  CUT ENGINES   (no movement, no turn)
-~  —  TURN LEFT     (no movement, left turn)
~-  —  TURN RIGHT    (no movement, right turn)
~~  —  COME FORWARD  (forward movement, no turn)
::  —  MOVE BACK     (backward movement, no turn)
/\  —  NORMAL STOP   (no movement, no turn)

Dies ist nicht die vollständige Liste der Marshalling-Signale, aber alles, was Sie unterstützen müssen.

Eingang

Die Eingabe ist eine durch Kommas getrennte Zeichenfolge, die Zeichenpaare enthält. Diese Zeichenfolge ist immer gültig - Sie müssen die Eingabe nicht validieren.

Ausgabe

Die Ausgabe ist ein Satz von Koordinaten wie oben beschrieben. Sie können dies in jedem geeigneten Format zurückgeben. Wenn Ihre Sprache mehrere Rückgabewerte unterstützt, können Sie dies verwenden. Alternativ können Sie eine Zeichenfolge (die Klammern um die Koordinaten sind nicht obligatorisch), ein Array, ein Tupel, eine Liste oder was auch immer Sie sonst noch für zweckmäßig halten, verwenden. Die einzige Regel ist , dass es enthalten muss x, yund hWerte, die in dieser Reihenfolge.

Testfälle

Input  —  Output
o/,~~,~~,~-,::  —  (-1, 2, E)
::,~-,o/,/\,~~,-~,~~,~~,~~  —  (-3, 1, W)
o/,::,-/,~~,o/,~-,~~,~~,~-  —  (2, -1, S)
o/,~-,~-,::,::,~-,~~,-~  —  (-1, 2, S)
~-,~-,o/,::,::,-/,~~,-~  —  (0, -2, N)
ArtOfCode
quelle
1
Was machen Startmotoren und Trennmotoren eigentlich? Werden nur die Bewegungen zwischen Startmotoren und Trennmotoren ausgeführt? Ansonsten sehe ich die Relevanz nicht.
Level River St
@LevelRiverSt "Ein Flugzeug kann sich nicht bewegen, wenn die Triebwerke ausgeschaltet sind." Ich habe das im Text durchgemacht.
ArtOfCode
Können wir, wenn wir eine Funktion schreiben, Eingaben als Liste von Anweisungen verwenden?
FlipTack
@ Flp.Tkc Kannst du die Herausforderung ändern, um es einfacher zu machen? Nein :)
ArtOfCode
Ich wusste nicht, dass die Verwendung einer eingebauten "Split" -Funktion so herausfordernd ist. Ein starres Eingabeformat für Code-Golf wird nicht empfohlen. Der Standard lautet "Nehmen Sie die Eingabe in einem beliebigen Format".
FlipTack

Antworten:

2

Java 8, 505 Bytes

Golf (mit Hilfe von @ masterX244 zum Rasieren eines großen Stücks)

class f{static boolean T(String u,String v){return u.equals(v);}public static void main(String[]a){java.util.Scanner q=new java.util.Scanner(System.in);String s=q.nextLine();int x=0;int y=0;int d=0;int[][]v={{0,1},{-1,0},{0,-1},{1,0}};int b=1;for(String r:s.split(",")){if(T(r,"o/")||T(r,"-/"))b=~1;if(b<0){if(T(r,‌​"~-"))d=(d+3)%4;if(T‌​(r,"-~"))d=(d+1)%4;i‌​f(T(r,"~~")){x+=v[d]‌​[0];y+=v[d][1];}if(T‌​(r,"::")){x-=v[d][0]‌​;y-=v[d][1];}}}Syste‌​m.out.println("("+x+‌​","+y+","+"NWSE".cha‌​rAt(d)+")");}}

Mehr lesbar

class f {
    static boolean T(String u,String v){return u.equals(v);}
    public static void main(String[] a) {
        java.util.Scanner q=new java.util.Scanner(System.in);
        String s=q.nextLine();
        int x=0;
        int y=0;
        int d=0;
        int[][] val = {
                {0,1},  // N
                {-1,0}, // W
                {0,-1}, // S
                {1,0}   // E
        };
        int b=1;
        for (String r: s.split(",")) {
            // toggle b if either start or stop engine
            if(T(r,"o/") || T(r,"-/"))
                b=~1;
            if(b<0){
                // right
                if(T(r,"~-")) d=(d+3)%4;
                // left
                if(T(r,"-~")) d=(d+1)%4;
                // come forward
                if(T(r,"~~")) {
                    x+=val[d][0];
                    y+=val[d][1];
                }
                // move back
                if(T(r,"::")) {
                    x-=val[d][0];
                    y-=val[d][1];
                }
            }
        }
        System.out.print("("+x+","+y+","+"NWSE".charAt(d)+")");
    }
}
Bobas_Pett
quelle
Einige freie Bytes: Eine Klasse, die main () enthält, muss nicht öffentlich sein (siehe die Golftipps für Java hier) und eine ganze Reihe von Leerzeichen, die optimiert werden können (alles neben nichtalphanumerischen Symbolen kann entfernt werden). auch false kann als 0> 1
masterX244
Außerdem: Wenn Sie den Bool durch einen Int ersetzen und vergleichen, dass er größer oder kleiner als Null ist, werden auch einige Bytes gespart. (mit * = - 1 umschalten) Code im nächsten Kommentar. Und verwenden Sie print () immer über println, wenn Sie nur eine Zeile
ausgeben
class f{static boolean T(String u,String v){return u.equals(v);}public static void main(String[]a){java.util.Scanner q=new java.util.Scanner(System.in);String s=q.nextLine();int x=0;int y=0;int d=0;int[][]v={{0,1},{-1,0},{0,-1},{1,0}};int b=1;for(String r:s.split(",")){if(T(r,"o/")||T(r,"-/"))b*=-1;if(b<0){if(T(r,"~-"))d=(d+3)%4;if(T(r,"-~"))d=(d+1)%4;if(T(r,"~~")){x+=v[d][0];y+=v[d][1];}if(T(r,"::")){x-=v[d][0];y-=v[d][1];}}}System.out.print("("+x+","+y+","+"NWSE".charAt(d)+")");}}
MasterX244
@ masterX244 thx das weiß ich doch ein bisschen.
Ich werde
Der Import ist auch ein Ort zur Optimierung. Für eine oder zwei Erwähnungen ist eine vollständig qualifizierte Referenz für beide kürzer als der Import. (Code, den ich in Kommentar eingefügt habe, enthält alle Optimierungen, die ich gefunden habe)
masterX244
1

Befunge, 201 185 Bytes

p10p2p3pv
~/3-*95~<v:+-"/"
  v!:-*53_v
 #_7-:v v0-1
vv!:-3_100>p
 _69*-:v NESW v+g01g
v v-*93_g10g\->4+4%10p
v<_100g >*:10g:1\-\2%!**03g+03p10g:2\-\2%**02g+02p
>>~65*`#v_2g.3g.10g9+5g,@

Probieren Sie es online aus!

Befunge hat keinen String-Typ als solchen. Um den Vergleich der Signale zu erleichtern, wird jedes Zeichenpaar mithilfe der Formel in eine Ganzzahl konvertiert (c1 - 45)/3 + c2 - 47. Dies kann bedeuten, dass bei ungültigen Eingaben falsche Übereinstimmungen angezeigt werden. Dies spielt jedoch keine Rolle, wenn die Eingabe garantiert gültig ist.

Der Rest des Codes basiert auf der Manipulation von vier „Variablen“: der Motor Zustand (1 oder 0), die Position (0 bis 3 für NESW) und die x und y - Positionen. Die Berechnungen für jedes Signal sind dann wie folgt:

Motor starten: engine = 1
Motor engine = 0
abstellen : Links abbiegen: heading = (heading - engine + 4) % 4
Rechts abbiegen: heading = (heading + engine) % 4
Bewegung: (wobei dir 1 für vorwärts und -1 für rückwärts ist)
y += dir*engine*(1-heading)*!(heading%2)
x += dir*engine*(2-heading)*(heading%2)

Sobald wir das Ende der Eingabesequenz erreicht haben, müssen nur noch x , y und die Überschrift ausgegeben werden (konvertiert in ein Zeichen mit einer einfachen Tabellensuche).

James Holderness
quelle
1

Python 2.7.12, 295 Bytes

from operator import*
l=[0,0]
m=[['N',[0,1]],['E',[1,0]],['S',[0,-1]],['W',[-1,0]]]
n=0
x=raw_input()
for c in x.split(','):
 if'o/'==c:n=1
 if'-/'==c:n=0
 if n:
    if'-~'==c:m=m[-1:]+m[:-1]
    if'~-'==c:m=m[1:]+m[:1]
    if'~~'==c:l=map(add,l,m[0][1])
    if'::'==c:l=map(sub,l,m[0][1])
print l+[m[0][0]]

Die erste Einrückungsstufe nach der forVerwendung einer einzelnen \s. Die Einrückung der zweiten Ebene verwendet eine einzelne \t. (Das Wysiwyg wird \tdurch mehrere Leerzeichen ersetzt. Bitte beachten Sie dies beim Testen der Größe.)

Eric
quelle
3
Es gibt viele überflüssige Leerzeichen, die Sie hier entfernen können.
ArtOfCode
Nicht nur Leerzeichen, sondern auch andere leicht zu behebende Ineffizienzen. Probieren Sie die Tipps zum Golfen in Python für bestimmte Beispiele.
Ad-hoc-Garf-Jäger
Beachten Sie, dass Sie beim Code-Golf keine Eingabeaufforderung benötigen: Sie können dies einfach tun raw_input().
FlipTack
Dieser Code ist für mich in Zeile 15 TypeError: Argument to map() must support iterationfehlerhaft : (Ich verwende Python 2.7.12).
Clismique
@ Qwerp-Derp, ich glaube ich habe den map () Fehler behoben.
Eric
1

Python 2, 142 Bytes

s=raw_input()
e=p=0;d=1
while s:exec'd-=e d+=e p+=1j**d*e e=0 0 e=1 p-=1j**d*e 0'.split()[ord(s[0])+ord(s[1])*2&7];s=s[3:]
print p,'ESWN'[d%4]

Beispiel:

% python2.7 ams.py <<<'o/,~~,~~,~-,::'
(-1+2j) E

Dies druckt komplexe Zahlen, was sollte in Ordnung sein, denke ich? Die x, y, hist , um immer noch da, und das 'j'verursacht keine Verwirrung. Sag mir, ob ich es ändern soll.

Lynn
quelle