Wo bin Ich jetzt?

21

Wo bin Ich jetzt?

Bestimmen Sie anhand einer Zeichenfolge d, die nur die Buchstaben enthält NSWE, die Koordinaten, die ich zurückgelegt habe (von links nach rechts, verbraucht), und die endgültige Koordinate, in der ich mich befinde.

Die Regeln zum Lesen von Koordinaten von links nach rechts:

  • Wenn das nächste Zeichen Noder istS :
    • Wenn das Zeichen nach dem Noder Sein anderes ist NoderS :
      • Verbrauchen Sie nur die erste Noder S.
      • Ausgabe [0,1] fürN
      • Ausgabe [0,-1]fürS
    • Wenn das Zeichen nach dem Noder Sist WoderE :
      • Verbrauchen Sie sowohl das Noder Sals auch das Woder E.
      • Ausgabe [1,1]bzw. [-1,1]für NEund NW.
      • Ausgabe [1,-1]bzw. [-1,-1]für SEund SW.
  • Wenn das Zeichen ein Eoder Wvoran nicht durch eine SoderN :
    • Verbrauchen die Eoder W.
    • Ausgabe [1,0]für E.
    • Ausgabe [-1,0]für W.

Gearbeitetes Beispiel

NSWE

[0,1]   (North      N)
[-1,-1] (South-west SW)
[1,0]   (East       E)
[0,0]   (N+SW+E = Didn't actually move)

Beachten Sie, dass dies in jedem Format sein kann. Hier sind andere Beispiele für eine gültige Ausgabe:

[[0,1],[-1,-1],[1,0],[0,0]]


[[[0,1],[-1,-1],[1,0]],[0,0]]


"0,1\n0,-1\n-1,0\n1,0\n0,0"

Etc...


Mehr Beispiele

SWSENNESWNE

[-1,-1]
[1,-1]
[0,1]
[1,1]
[-1,-1]
[1,1]
[1,0]

NIEESESSWWNW

[0,1]
[1,1]
[1,0]
[1,-1]
[0,-1]
[-1,-1]
[-1,0]
[-1,1]
[0,0]

NENENEE

[1,1]
[1,1]
[1,1]
[1,0]
[4,3]

Nen

[1,1]
[0,1]
[1,2]

EEE

[1,0]
[1,0]
[1,0]
[3,0]

Regeln

  • Sie können in jedem geeigneten Format ausgeben, das keine Regelungslücken verletzt.
  • Sie müssen gierig konsumieren, NWEist nie N,W,E, es ist immer NW,E.
    • Dies gilt für: SW*, SE*, NW*, NE*.
    • Sie konsumieren gierig von links nach rechts.
  • Das ist , die niedrigste Anzahl an Bytes gewinnt.
Magische Kraken-Urne
quelle
"bestimme die Koordinaten, die ich bereist habe" : Ich bin mir nicht sicher, ob es wirklich mit dem übereinstimmt, was danach beschrieben wird. Es ist eher so, als würde man "die Vektoren aller meiner Züge bestimmen" . Nur die endgültige Ausgabe sind tatsächliche Koordinaten.
Arnauld
1
Ein Testfall, zu dem man läuft, [4, 3]würde es ein wenig einfacher machen zu sehen, was in der Testausgabe vor sich geht.
Lynn
3
Sind komplexe Zahlen formatiert 1, -1j, (-1+1j)etc ein gültiges Ausgabeformat?
Lynn
2
Aufgrund des Fehlens dieses Falls in den angegebenen Regeln und Beispielen gehe ich davon aus, dass der Eingabe-String niemals mit einem 'N' oder 'S' endet.
Kevin Cruijssen
1
Ist gierig essen eigentlich anders als nicht? Da NEist doch einfach N+Enicht egal?
Weizen-Assistent

Antworten:

7

Python 2 , 116 Bytes

import re
a=[(int(s,35)%5-3,('N'in s)-('S'in s))for s in re.findall('[NS][EW]?|.',input())]
print a,map(sum,zip(*a))

Probieren Sie es online!

Bei Ausgabe als [(3+4j), 1, -1j, …]91 Bytes

lambda x:[sum(1j**(ord(c)%8%5)for c in s)for s in[x]+re.findall('[NS][EW]?|.',x)]
import re

Probieren Sie es online!

Dieses Lambda gibt eine Liste von Gaußschen Ganzzahlen zurück : Die erste ist die endgültige Koordinate, und alle anderen sind die Schritte, die erforderlich sind, um dorthin zu gelangen.

Lynn
quelle
5

Attache , 80 Bytes

V#Sum##{Chop[1-ToBase[22260446188,3],2][Sum@Ords=>MatchAll[_,/"[NS][WE]|."]%11]}

Probieren Sie es online!

Dies ist eine anonyme Funktion, die ein String-Argument akzeptiert.

Erläuterung

Die erste Aufgabe besteht darin, die Analysephase dieser Frage zu implementieren. Ich fand es am kürzesten, einen einfachen Regex zu verwenden, um die Eingabe zu analysieren ( _):

MatchAll[_,/"[NS][WE]|."]

Dies entspricht allen Vorkommen des regulären Ausdrucks [NS][WE]|., wie in vielen anderen Antworten zu sehen ist. Dies ergibt gierig die angeforderten Richtungen.

Jetzt wenden wir auf jede Richtung eine Hash-Funktion an. Wir nehmen die Codepunkte jeder Richtung und summieren sie. Dies ergibt das folgende Mapping:

Direction       Ord-sum
E               69
N               78
S               83
W               87
NE              147
SE              152
NW              165
SW              170

Wir werden versuchen, diese Werte einer kleineren Domäne zuzuordnen. Modulo ist dafür nützlich, und wir können zeigen, dass das kleinste Modulo, das zu eindeutigen Werten für alle angegebenen Eingaben führt, 11 ist. Nach Resten sortiert ergibt dies die folgende Tabelle:

Direction       Ord-sum         % 11
NW              165             0
N               78              1
E               69              3
NE              147             4
SW              170             5
S               83              6
SE              152             9
W               87              10

Jetzt haben wir eine Eingabekorrespondenz, als Kodierung von Sum@Ords=>[...]%11. Als nächstes müssen wir diese Reste in Punkte umwandeln. Wir werden versuchen, eine andere Zuordnung abzuleiten, was bedeutet, dass das Einfügen von "dünn besetzten Werten" in Hashes, die nicht den Anweisungen entsprechen, nützlich ist:

Direction       Hash        Coordinates
NW              0           [-1, 1]
N               1           [0, 1]
--             (2)          [0, 0]
E               3           [1, 0]
NE              4           [1, 1]
SW              5           [-1, -1]
S               6           [0, -1]
--             (7)          [0, 0]
--             (8)          [0, 0]
SE              9           [1, -1]
W               10          [-1, 0]

Wir haben derzeit eine Reihe von Punkten, die eine durch den Hash indizierbare Liste ergeben können:

[-1, 1] [0, 1] [0, 0] [1, 0] [1, 1] [-1, -1] [0, -1] [0, 0] [0, 0] [1, -1] [-1, 0]

Nun werden wir dies komprimieren, da es nur aus -1s, 0s und 1s besteht. Da die Liste Paare darstellt, können wir die Liste reduzieren, ohne Daten zu verlieren. Wenn wir dann jede Zahl nehmen xund berechnen 1-x, erhalten wir die folgende Liste:

2 0 1 0 1 1 0 1 0 0 2 2 1 2 1 1 1 1 0 2 2 1

Wir können dies in eine Zahl zur Basis 3 umwandeln:

20101101002212111102213

Umstellung auf Basis 10:

20101101002212111102213 ≡ 2226044618810

Zusammenfassend haben wir unsere Punkte genommen, sie entkoppelt, jedes Element 1von der Basis subtrahiert und von ihr konvertiert 3, um sie zu erhalten 22260446188. Wir können als solche dekomprimieren:

  1. In Basis 3 konvertieren: ToBase[22260446188,3]
  2. Nimm jede Zahl von einer subtrahiert (selbstinvers): 1-ToBase[22260446188,3]
  3. Liste erneut koppeln: Chop[1-ToBase[22260446188,3],2]

Dies gibt uns unseren ursprünglichen Satz von Paaren. Dann können wir die oben erwähnte Indizierung wie folgt durchführen:

(chopped value)[hashes]

Da die Indizierung durch ein Array in Attache alle Elemente zurückgibt, die diesen Indizes entsprechen. (Also [1,2,3,4][ [0,0,-1,1] ] = [1,1,4,2],.) Nun haben wir die Richtungen des Weges, den der OP gegangen ist. Was bleibt, ist die Berechnung der Summe.

Also erfassen wir dieses Ergebnis in einem Lambda {...}und setzen es als erste Funktion in eine Funktionszusammensetzung ( a##b), wobei die zweite Funktion ist V#Sum. Dies ist eine Gabel, die sich bei Eingabe wie folgt xerweitert:

V[x, Sum[x]]

SumWenn ein 2D-Array angegeben wird, summiert sich jede Spalte im Array (als Ergebnis einer vektorisierten Summierung). Auf diese Weise werden die Anweisungen mit dem endgültigen Ziel verknüpft, und wir haben unser endgültiges Ergebnis.

Conor O'Brien
quelle
4

JavaScript (ES6), 102 Byte

Gibt eine Zeichenfolge zurück.

s=>s.replace(/[NS][EW]|./g,s=>(D=d=>!!s.match(d),x+=h=D`E`-D`W`,y+=v=D`N`-D`S`,[h,v]+`
`),x=y=0)+[x,y]

Probieren Sie es online!

Arnauld
quelle
Ich mag die Verwendung von Template-Funktionen! : D
Conor O'Brien
@ ConorO'Brien Ja, sie sind hier ziemlich praktisch. Alle Zaubersprüche, die ich bisher beschworen habe, sind mindestens ein bisschen länger.
Arnauld
4

MATL , 45 Bytes

'NS' 'WE'Z*Z{2MhX{h'eklihfmj'X{YX9\3_2&YAqts

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Erklärung (mit Beispiel)

Betrachten Sie die Eingabe 'NSWE'als Beispiel.

'NS' 'WE'  % Push these two strings
           % STACK: 'NS', 'WE'
Z*         % Cartesian product. Gives a 4×2 char matrix
           % STACK: ['NW'; 'NE'; 'SW'; 'SE']
Z{         % Cell array of rows (strings)
           % STACK: {'NW', 'NE', 'SW', 'SE'}
2M         % Push again the inputs of the second-last function call
           % STACK: {'NW', 'NE', 'SW', 'SE'}, 'NS', 'WE'
h          % Concatenate horizontally
           % STACK: {'NW', 'NE', 'SW', 'SE'}, 'NSWE'
X{         % Cell array of individual elements (chars)
           % STACK: {'NW', 'NE', 'SW', 'SE'}, {'N', 'S', 'W', 'E'}
h          % Concatenate horizontally
           % STACK: {'NW', 'NE', 'SW', 'SE', 'N', 'S', 'W', 'E'}
'eklihfmj' % Push this string
           % STACK: {'NW', 'NE', 'SW', 'SE', 'N', 'S', 'W', 'E'}, 'eklihfmj'
X{         % Cell array of individual elements (chars)
           % STACK: {'NW','NE','SW','SE','N','S','W','E'},{'e','k','l','i','h','f','m','j'}
YX         % Implicit input. Regexp replace: replaces 'NW' by 'e', then 'NE' by 'k', etc.
           % Note that the two-letter combinations are replaced first, which implements
           % the greediness; and the target letters do not appear in the source, which
           % avoids unwanted interactions between replacements
           % STACK: 'hlj'
9\         % Modulo 9 (of codepoints), element-wise
           % STACK: [5, 0, 7]
3_2&YA     % Convert to base 3 with 2 digits. Gives a 2-column matrix
           % STACK: [1, 2; 0, 0; 2, 1]
q          % Subtract 1, element-wise
           % STACK: [0, -1; -1, -1; 1, 0]
tXs        % Duplicate. Sum of each column
           % STACK: [0, -1; -1, -1; 1, 0], [0, 0]
           % Implicit display
Luis Mendo
quelle
4

Java (JDK 10) , 171 Byte

s->{var r="";int i=0,l=s.length,c,x=0,y=0,Y,X;for(;i<l;X=c>1||i<l&&(c=~-s[i]/6%4)>1&&++i>0?c*2-5:0,r+=X+","+Y+" ",x+=X,y+=Y)Y=(c=~-s[i++]/6%4)<2?1-c*2:0;return r+x+","+y;}

Probieren Sie es online!

Erklärungen

Dank c=~-s[i]/6%4wird das folgende Mapping durchgeführt:

'N' -> ascii: 78 -> -1 = 77 -> /6 = 12 -> %4 = 0
'S' -> ascii: 83 -> -1 = 83 -> /6 = 13 -> %4 = 1
'W' -> ascii: 87 -> -1 = 86 -> /6 = 14 -> %4 = 2
'E' -> ascii: 69 -> -1 = 68 -> /6 = 11 -> %4 = 3
  • NSwird geprüft , mit c<2und zugeordnet +1/ -1mit 1-c*2;
  • EWwird geprüft , mit c>1und zugeordnet +1/ -1mit c*2-5.

Credits

Olivier Grégoire
quelle
Ah, Sie haben Ihre Java-Antwort gepostet, während ich meine Erklärung eingetippt habe. :) Da wir beide einen völlig anderen Ansatz verfolgen, werde ich meinen vorerst verlassen. Zu schlechte Variablen, die in Lambdas verwendet werden, müssen effektiv final sein, andernfalls hätten Sie eine Zeichenfolge anstelle einer Liste zurückgeben können, um Bytes zu speichern.
Kevin Cruijssen
Danke, es hat nur ein paar Bytes gespart (4), aber es ist besser als nichts;)
Olivier Grégoire
@KevinCruijssen Danke, es schien zunächst ziemlich offensichtlich, aber ich arbeitete an einem anderen Ansatz, der meine Byteanzahl um mehr als 30 reduzierte. Ein "Parsing", kein "Matching".
Olivier Grégoire
1
Seufz .. 172 Bytes
Kevin Cruijssen
1
@KevinCruijssen Tut mir leid, es ist ein Durcheinander, das Ihre Änderungen einbezieht ... Ich bin bei der Arbeit beschäftigt und vergesse, diese Seite zu aktualisieren ... Trotzdem vielen Dank ^^ 'Die Gutschrift liegt sehr wahrscheinlich unter Ihrer tatsächlichen Gutschrift. Sorry auch dafür: s
Olivier Grégoire
3

Retina 0.8.2 , 93 Bytes

.+
$&¶$&
\G[NS]?[EW]?
$&¶
G`.
W
J
%O`.
+`EJ|NS

m`^((J)?[EJ]*)((S)?[NS]*)
$#2$*-$.1,$#4$*-$.3

Probieren Sie es online! Erläuterung:

.+
$&¶$&

Duplizieren Sie die Eingabe.

\G[NS]?[EW]?
$&¶

Teilen Sie die erste Kopie in Richtungen auf.

G`.

Entfernen Sie überflüssige Leerzeilen, die durch den obigen Vorgang erzeugt wurden.

W
J

Ändern Sie Win, Jso dass es zwischen Eund sortiert N. (Wechseln Ezwischen Sund Wwürde auch funktionieren.)

%O`.

Sortieren Sie jede Zeile in der Reihenfolge.

+`EJ|NS

Löschen Sie Paare entgegengesetzter Richtungen (dies betrifft natürlich nur die letzte Zeile).

m`^((J)?[EJ]*)((S)?[NS]*)
$#2$*-$.1,$#4$*-$.3

Zählen Sie die Anzahl der horizontalen und vertikalen Bewegungen und fügen Sie gegebenenfalls Zeichen hinzu.

Diejenigen von euch, die die Unterschiede zwischen Retina 0.8.2 und Retina 1 kennen, werden darauf hinweisen wollen, dass ich in Retina 1 2 Bytes einsparen kann, weil es *anstelle von verwendet $*. Während ich dort war, habe ich versucht, den Aufteilungsprozess zu vereinfachen, aber ich konnte die Byteanzahl nicht weiter reduzieren, ich konnte es nur so ausgleichen:

L$`$(?<=(.*))|[NS]?[EW]?
$&$1
Neil
quelle
3

Java 10, 269 265 243 Bytes

s->{var r="";int x=0,y=0,t,X,Y,a;for(;!s.isEmpty();r+=X+"|"+Y+" ",s=s.substring(++t),x+=X,y+=Y){a=s.charAt(t=0);if(s.matches("[SN][WE].*")){X=s.charAt(1)<70?1:-1;Y=1-a%2*2;t++;}else{X=a<70?1:a>86?-1:0;Y=a>69&a<87?1-a%2*2:0;}}return r+x+"|"+y;}

Auf jeden Fall nicht die richtige Sprache für diese Herausforderung.

Probieren Sie es online aus.

Erläuterung:

s->{                  // Method with String as both parameter and return-type
  var r="";           //  Result-String, starting empty
  int x=0,            //  Ending `x`-coordinate, starting at 0
      y=0,            //  Ending `y`-coordinate, starting at 0
      t,X,Y,a;        //  Temp-integers
  for(;!s.isEmpty()   //  Loop as long as the input-String is not empty yet
      ;               //    After every iteration:
       r+=X+"|"+Y+" ",//     Append the current steps to the result-String
       s=s.substring(t),
                      //     Remove the first `t` characters from the input-String
       x+=X,y+=Y){   //      Append the ending `x`,`y` coordinates with the steps
    a=s.charAt(0);   //    Set `a` to the first character of the input-String to save bytes
    t=1;             //    Set `t` to 1
    if(s.matches("[SN][WE].*")){
                     //   Else-if the input-String starts with N/S followed by E/W:
      X=s.charAt(1)<70?1:-1;
                     //    Set `X` to 1 if 'E', -1 if 'W'
      Y=1-a%2*2;     //    Set `Y` to 1 if 'N', -1 if 'S'
      t++;}          //    Increase `t` by 1
    else{            //   Else:
      X=a<70?1:a>86?-1:0;
                     //    Set `X` to 1 if 'E', -1 if 'W', 0 if 'N' or 'S'
      Y=a>69&a<87?1-a%2*2:0;}}
                     //    Set `Y` 1 if 'N', -1 if 'S', 0 if 'E' or 'W'
  return r+x+"|"+y;} //  Append the ending coordinates, and return the result-String
Kevin Cruijssen
quelle
1
Java-Antworten bekommen Punkte, weil jeder sie bekommt :).
Magic Octopus Urn
@MagicOctopusUrn True. :) Und ich spiele immer noch gerne mit Java, auch wenn Sie nie die kürzeste Antwort sein werden. Es sei denn, Sie sind die einzige Antwort (haben zwei akzeptierte Java-Antworten erhalten. XD). Für diese Herausforderung ist die Java-Antwort von OlivierGrégoire jedoch etwa 70 Byte kürzer, sodass die meisten Upvotes an ihn gehen sollten.
Kevin Cruijssen
2

Perl 5 -n , 94 Bytes

$x=$y=0;%X=qw/E ++ W --/;%Y=qw/N ++ S --/;s%(N|S)?(E|W)?%"say $X{$2}\$x.','.$Y{$1}\$y"if$&%gee

Probieren Sie es online!

Xcali
quelle
2

JavaScript (ES6), 102 Byte

f=
s=>s.replace(/((N)|(S))?((E)|(W))?/g,(m,v,n,s,h,e,w)=>(x+=h=!w-!e,y+=v=!s-!n,m?[h,v]+`
`:[x,y]),x=y=0)
<input oninput=o.textContent=/[^NSEW]/.test(this.value)?``:f(this.value)><pre id=o>0,0

Gibt eine Zeichenfolge zurück.

Neil
quelle
1

Ruby , 75 71 Bytes

->x{[*x.scan(/[NS][EW]?|./),x].map{|s|s.chars.sum{|c|1i**(c.ord%8%5)}}}

Probieren Sie es online!

-4 Bytes dank benj2240.

Da die Rückgabe komplexer Zahlen ein akzeptables Ausgabeformat zu sein scheint, wird es wohl nicht viel golfener, als nur die sehr nette Antwort von Lynn zu portieren .

Kirill L.
quelle
Sehr schön. Sie können ein paar Bytes sparen, indem Sie das Innere überspringen mapund seinen Block direkt an sumfolgende Adresse übergeben
benj2240
1

F # (Mono) , 269 Bytes

let f s=
 let l,h=(string s).Replace("NW","A").Replace("NE","B").Replace("SW","C").Replace("SE","D")|>Seq.map(function 'N'->0,1|'S'->0,-1|'W'-> -1,0|'E'->1,0|'A'-> -1,1|'B'->1,1|'C'-> -1,-1|'D'->1,-1)|>Seq.mapFold(fun(x,y) (s,t)->(s,t),(x+s,y+t))(0,0)
 Seq.append l [h]

Probieren Sie es online!

Henrik Hansen
quelle
Hallo, willkommen bei PPCG. Leider fehlt Ihnen das letzte Element Ihrer Ausgabe. Dies sollte die Position sein, an der Sie geendet haben. Also für die, die NSWESie gerade ausgeben (0,1), (-1,-1)sollte (1,0)eine vierte Ausgabe die Summe dieser Koordinaten sein, also (0,0)(weil 0+-1+1 = 0und 1+-1+0 = 0).
Kevin Cruijssen
@ KevinCruijssen OK, das habe ich nicht verstanden. Update gemacht.
Henrik Hansen
1
Scheint jetzt großartig zu funktionieren, also +1 von mir. Genieße deinen Aufenthalt! :) Und falls Sie es noch nicht gesehen haben, könnten Tipps zum Golfen in F # und Tipps zum Golfen in <allen Sprachen> interessant sein, durchzulesen.
Kevin Cruijssen
1

sed, 125

Das Nehmen von Freiheiten mit Ausgabeformatversion :

Die Bewertung enthält +1 für den -rzu sedierenden Parameter.

s/(N|S)(E|W)/\L\2,\1 /g
s/N|S/,& /g
s/E|W/&, /g
s/N|E/A/gi
s/S|W/a/gi
p
:
s/(\S*),(\S*) (\S*),(\S*)/\1\3,\2\4/
t
s/Aa|aA//
t

Probieren Sie es online aus .

Die Ausgabe ist wie folgt:

  • Koordinatenelemente sind durch Kommas getrennt
  • Jeder Koordinatensatz ist durch Tabulatoren getrennt
  • Die endgültige Koordinate befindet sich in einer neuen Zeile
  • Alle Zahlen sind in ℤ-Unary:
    • Eine Zeichenfolge steht für Adie + ve Ganzzahllen(string)
    • Eine Zeichenfolge steht für adie Ganzzahl -ve-len(string)
    • die leere Zeichenfolge steht für 0

Beispielsweise:

  • , ist [0,0]
  • ,AA ist [0,2]
  • aaa, ist [-3,0]

sed 4.2.2 einschließlich GNU exec extension , 147

Die sinnvolle Ausgabeformatversion :

Die Bewertung enthält +1 für den -rzu sedierenden Parameter.

s/(N|S)(E|W)/\L\2 \1\n/g
s/N|S/0 &\n/g
s/E|W/& 0\n/g
s/N|E/1/gi
s/S|W/-1/gi
p
:
s/(\S+) (\S+)\n(\S+) (\S+)/\1+\3 \2+\4/
t
s/\S+/$[&]/g
s/^/echo /e

Die Ausgabe erfolgt als durch Leerzeichen getrennte Koordinaten, eine pro Zeile. Zwischen dem vorletzten und dem letzten Satz von Koordinaten gibt es einen zusätzlichen Zeilenumbruch - nicht sicher, ob das problematisch ist oder nicht.

Probieren Sie es online!

Digitales Trauma
quelle
0

PHP, 153 Bytes

lass einen Regex die Aufteilung machen; Durchlaufen Sie die Übereinstimmungen, drucken Sie die Zwischenergebnisse aus und fassen Sie sie zusammen:

preg_match_all("/[NS][EW]?|E|W/",$argn,$m);foreach($m[0]as$s){$x+=$p=strtr($s[-1],NEWS,1201)-1;$y+=$q=strtr($s[0],NEWS,2110)-1;echo"$p,$q
";}echo"$x,$y";

Laufen Sie als Pipe mit -nRoder versuchen Sie es online .

Titus
quelle
0

C (gcc) 173 Bytes

Es ist interessant, dies in einer Sprache ohne Regex-Unterstützung zu tun!

f(char*s){char*t="[%d,%d]\n";int x[4]={0},i;for(;*s;*x=x[1]=!printf(t,x[1],*x))for(i=-1;i<5;)if(*s=="S NW E"[++i]){x[i/3+2]+=x[i/3]=i%3-1;i+=2-i%3;s++;}printf(t,x[3],x[2]);}

Probieren Sie es online!

ErikF
quelle
164 Bytes
Ceilingcat