Relativ gegen Absolut

17

Wenn jemand, der an Punkt A in diesem Raster nach Norden zeigt, dem grünen Pfad folgen möchte (da er nur den Rasterlinien folgen kann), können Sie ihm Folgendes mitteilen:

Geh North, North, West, East, East, South, East, East.

oder äquivalent

Geh Forward, Forward, Left, Back, Forward, Right, Left, Forward.
(Wenn ein Rechts- , Links- oder Rückwärtsbefehl implizit bedeutet, dass Sie sich in diese Richtung drehen, gehen Sie vorwärts.)

Weg von A nach B

Schreiben Sie eine Funktion mit einem Argument, das zwischen diesen absoluten und relativen Richtungen auf demselben Pfad und nicht nur zum selben Punkt übersetzt. Angenommen, die gerichtete Person fängt immer an, nach Norden zu blicken.

Wenn das Argument eine Zeichenfolge aus Buchstaben ist NSEW, geben Sie die entsprechenden relativen Richtungen zurück.
zB f("NNWEESEE")gibt den String zurück FFLBFRLF.

Wenn das Argument eine Zeichenfolge aus Buchstaben ist FBLR, geben Sie die entsprechenden absoluten Richtungen zurück.
zB f("FFLBFRLF")gibt den String zurück NNWEESEE.

Der leere String ergibt sich von selbst. Angenommen, keine anderen Eingabefälle.

Wenn Ihre Sprache keine Funktionen oder Zeichenfolgen enthält, verwenden Sie die am besten geeignete Option.

Der kürzeste Code in Bytes gewinnt.

Calvins Hobbys
quelle
Gehen wir davon aus, dass eine Person immer mit dem Kopf nach Norden beginnt? Auf diese Weise relativ gesehen in Richtung Osten zu gehen, wäre es erforderlich , ihn nach rechts zu drehen, anstatt einfach zu sagen , nach vorne
Optimizer
@Optimizer Ja, nach Norden. Und ja zu deinem anderen Punkt. Rgleich Ezu Beginn.
Calvins Hobbys
1
Yay! Du hast dein Bild geändert, um zu bestätigen, was ich immer gedacht habe!
Justin
4
Bist du wieder von PPCG begeistert? ;)
Martin Ender
4
@ MartinBüttner Entweder das oder ich kann meine Hausaufgabenprobleme sehr gut verschleiern. ;)
Calvins Hobbys

Antworten:

6

CJam, 57 53 49

{"NESW""FRBL"_3$&!!:Q$:R^^f#0\{{+0\}Q*_@-R=\}%);}

Vorherige Version

{"NESW""FRBL"_3$0=#W>:Q{\}*:R;f#0\{{+0\}Q*_@-R=\}%);}

Beispiel:

{"NESW""FRBL"_3$0=#W>:Q{\}*:R;f#0\{{+0\}Q*_@-R=\}%);}:T;
"NNWEESEE"T
N
"FFLBFRLF"T

Ausgabe:

FFLBFRLF
NNWEESEE

Wie es funktioniert

{
  "NESW""FRBL"             " Push the two strings. ";
  _3$0=#W>                 " Check if the first character is in FRBL. ";
  :Q                       " Assign the result to Q. ";
  {\}*                     " Swap the two strings if true. ";
  :R;                      " Assign the top string to R and discard it. ";
  f#                       " Find each character of the input in the string. ";
  0\                       " Push a 0 under the top of the stack. ";
  {                        " For each item (index of character): ";
    {                      " If Q: ";
      +0\                  " A B -> 0 (A+B) ";
    }Q*
    _@-                    " C D -> D (D-C) ";
    R=                     " E -> E-th character in R ";
    \                      " Swap the top two items. ";
  }%
  );                       " Discard the last item in the list. ";
}
jimmy23013
quelle
6

C ++, 99 97

Das Folgende ist als Lambda-Ausdruck formatiert. Es braucht ein char*Argument und überschreibt es.

[](char*s){for(int d=0,n=0,c=*s*9%37&4;*s;d+=n)c?n=*s%11/3-d:n+=*s%73%10,*s++="NESWFRBL"[c|n&3];}

Für diejenigen, die mit dieser Funktion nicht vertraut sind (wie ich vor 1 Stunde), verwenden Sie sie wie folgt:

#include <iostream>

int main()
{
    char s[] = "NNWEESEE";
    auto x = [](char*s){for(int d=0,n=0,c=*s*9%37&4;*s;d+=n)c?n=*s%11/3-d:n+=*s%73%10,*s++="NESWFRBL"[c|n&3];};

    x(s); // transform from absolute to relative
    std::cout << s << '\n';

    x(s); // transform from relative to absolute
    std::cout << s << '\n';
}

Einige Erklärungen:

  • Wenn Sie Code wie verwenden flag ? (x = y) : (x += z), ist das zweite Klammerpaar in C erforderlich. Also habe ich stattdessen C ++ verwendet!
  • C ++ erfordert die Angabe eines Rückgabetyps für eine Funktion. Es sei denn, ich verwende einen Lambda-Ausdruck! Ein zusätzlicher Bonus ist, dass ich nicht 1 Zeichen für den Namen der Funktion verschwenden muss.
  • Der Code *s*9%37&4testet das erste Byte. das Ergebnis ist 4, wenn es eines von ist NESW; 0 sonst
  • Der Code *s%11/3konvertiert die Bytes NESWin 0, 1, 2, 3
  • Der Code *s%73%10konvertiert die Bytes FRBLin 0, 9, 6, 3 (was 0, 1, 2, 3 Modulo 4 ist)
  • Beim Konvertieren von relativen Richtungen in absolute Richtungen benötige ich die dVariable nicht. Ich habe versucht, den Code neu anzuordnen, um ihn vollständig zu entfernen, aber es scheint unmöglich ...
anatolyg
quelle
1
Ich mag es sehr, wie Sie die Buchstaben in Zahlen umwandeln. :)
Emil
6

JavaScript (E6) 84 86 88 92 104

Bearbeiten: Verwenden von & anstelle von%, andere Operatorpriorität (weniger Klammern) und besseres Arbeiten mit negativen Zahlen
Bearbeiten2: | statt + wieder op Priorität -2. Dank DocMax
Edit3: Das Array-Verständnis ist für Zeichenfolgen 2 Zeichen kürzer als für map ()

F=p=>[o+=c[d=n,n=c.search(i),n<4?4|n-d&3:n=n+d&3]for(i of n=o='',c='NESWFRBL',p)]&&o

Test In FireFox / Firebug - Konsole

console.log(F('NNWEESEE'),F('FFLBFRLF'))

Ausgabe

FFLBFRLF NNWEESEE
edc65
quelle
@Optimizer nicht mehr. Und in der Hoffnung, noch mehr zu schrumpfen.
EDC65
Was bedeutet && oam Ende?
Bebe
2
@bebe die Map-Funktion gibt ein Array zurück, in dem ich als Nebeneffekt die o-Zeichenfolge fülle, die ich zurückgeben muss. array && valueWie valuejedes Array auswertentruthy
edc65
1
Endlich! Ich habe in diesem einen gestarrt , da es 88 getroffen Es sei denn , ich bin etwas fehlt, können Sie ersetzen 4+(n-d&3)mit 4|n-d&3und speichern 2 Zeichen.
DocMax
4

APL, 72

{^/⍵∊A←'NESW':'FRBL'[1+4|-2-/4,3+A⍳⍵]⋄A[1+4|+\'RBLF'⍳⍵]}

Wenn die Interpreter-Konfigurationen ohne Abzug geändert werden können, beträgt die Punktzahl 66 , indem geändert wird ⎕IOzu 0:

{^/⍵∊A←'NESW':'FRBL'[4|-2-/0,A⍳⍵]⋄A[4|+\'FRBL'⍳⍵]}
TwiNight
quelle
3

Python, 171 139

Nicht annähernd so kurz wie die anderen Lösungen, aber ich denke, es sollte relativ gut für das sein, was mit Python gemacht werden kann:

def f(i):a,b='NWSE','FLBR';I=map(a.find,'N'+i);return''.join((b[I[k+1]-I[k]],a[sum(map(b.find,i)[:k+1])%4])[-1in I]for k in range(len(i)))

Erweiterte Version für etwas bessere Lesbarkeit:

def f(i):
    a, b = 'NWSE', 'FLBR'
    I = map(a.find,'N'+i)     # translate to numbers assuming abs. directions
    J = map(b.index,i)        # translate to numbers assuming rel. directions
    if not -1 in I:
        o = [b[I[k+1]-I[k]] for k in range(len(i))]    # rel. dir. is differences of abs. dir.
    else:
        o = [a[sum(J[:k+1])%4] for k in range(len(i))] # abs. dir. is sum of all rel. dir. so far
    return ''.join(o)
Emil
quelle
1

Los, 201

type q string;func F(s q)q{d,z:=byte(0),make([]byte,len(s));for i,c:=range[]byte(s){if(c^4)*167%3<2{c=c*156%5;z[i],d="LBRF"[(d-c)%4],c-1;}else{c=(c^43)*3%7-1;d=(d+c)%4;z[i]="NESW"[d];};};return q(z);}

Lesbare Version:

func F(s string) string {
    d, z, R, A := 0, make([]byte, len(s)), "LBRFLBR", "NESW"
    for i, c := range []byte(s) {
        switch c {
        case 'N': c = R[d+3]; d = 0
        case 'E': c = R[d+2]; d = 1
        case 'S': c = R[d+1]; d = 2
        case 'W': c = R[d]; d = 3
        case 'F': c = A[d]
        case 'R': d = (d + 1) % 4; c = A[d]
        case 'B': d = (d + 2) % 4; c = A[d]
        case 'L': d = (d + 3) % 4; c = A[d]
        }
        z[i] = c
    }
    return string(z)
}

David
quelle
1

GNU sed, 356 Bytes

Die Herausforderung erfordert eine einfache Transformation eines Zeichenstroms. sedder stream editor ist die naheliegende sprachenwahl ;-)

/[FRBL]/bx                                     # Jump to label x if relative
:y                                             # label y (start of abs->rel loop)
/[FRBL]$/q                                     # quit if string ends in rel char
s/(^|[FRBL])N/\1F/;ty                          # Substitute next abs char with
s/(^|[FRBL])E/\1R/;tr                          #     rel char, then jump to
s/(^|[FRBL])S/\1B/;tb                          #     relevant rotation label if
s/(^|[FRBL])W/\1L/;tl                          #     a match was found
by                                             # loop back to y
:r;y/NESW/WNES/;by                             # Rotation labels: transform then
:b;y/NESW/SWNE/;by                             #     loop back to y
:l;y/NESW/ESWN/;by
:x                                             # label x (start of rel->abs loop)
/^[NESW]/q                                     # quit if string starts w/ abs char
/F([NESW]|$)/s/F([NESW]|$)/N\1/                # Matches for each direction:
/R([NESW]|$)/y/NESW/ESWN/;s/R([NESW]|$)/E\1/   #     rotate, then substitute
/B([NESW]|$)/y/NESW/SWNE/;s/B([NESW]|$)/S\1/
/L([NESW]|$)/y/NESW/WNES/;s/L([NESW]|$)/W\1/
bx                                             # loop back to x

(Kommentare und Leerzeichen, die für die Berechnung des Golfscores entfernt wurden)

Ausgabe:

$ sed -rf absrel.sed <<< NNWEESEE
FFLBFRLF
$ sed -rf absrel.sed <<< FFLBFRLF
NNWEESEE
$ 

Erläuterung:

Die Idee dabei ist, dass es beim Ändern des Referenzrahmens immer eine direkte Zuordnung zwischen {N, E, S, W}und gibt{F, R, B, L} .

Im Fall von absolut zu relativ arbeiten wir uns vorwärts durch die Zeichenkette. Für jedes Zeichen bilden wir {N, E, S, W}an {F, R, B, L}, und drehen Sie dann die restlichen[NESW] Zeichen nach dem Charakter , den wir gerade abgebildet wird , dann auf das nächste Zeichen bewegen.

Für den Fall von relativ zu absolut machen wir das Gegenteil. Wir arbeiten die Zeichenfolge rückwärts durch und drehen alle folgenden [NESW]Zeichen entsprechend dem Zeichen unmittelbar davor. Dann ordnen wir dieses Zeichen {N, E, S, W}zu {F, R, B, L}, bis wir am Anfang der Zeichenkette angelangt sind.

Digitales Trauma
quelle
0

Haskell, 224

import Data.Function
i=flip(\x->length.takeWhile(/=x))
r=['F','R','B','L']
a=['N','E','S','W']
f s@(x:_)|elem x a=map((r!!).(`mod`4).(4-))$zipWith((-)`on`(i a))('N':s)(s)|True=tail$map((a!!).(`mod`4)).scanl(+)(0)$map(i r) s

Dies ordnet den relativen Richtungen Rotationsnummern und den absoluten Richtungen Orientierungsnummern zu und findet dann entweder die Rotationen zwischen aufeinanderfolgenden Orientierungen oder die Orientierungen nach aufeinanderfolgenden Rotationen. Die iFunktion findet den Index innerhalb der beiden Legenden.

Archaephyrryx
quelle