Avast, ihr Scallywags!

10

Blackbeard war ein englischer Pirat des frühen 18. th Jahrhundert. Obwohl er dafür bekannt war, Schiffe zu plündern und zu nehmen, befehligte er seine Schiffe mit Erlaubnis ihrer Besatzungen. Es gibt keine Berichte darüber, dass er jemals seine Gefangenen verletzt oder ermordet hat.

Diese Herausforderung ist zu Ehren des berüchtigten Blackbeard und inspiriert vom International Talk Like a Pirate Day (19. September). Es ist auch das Gegenteil dieser Herausforderung von Pyrrha .


Die Herausforderung

Erstellen Sie ein Programm, das eine Schatzkarte als Eingabe verwendet (bestehend aus den unten aufgeführten Zeichen) und deren Anweisungen ausgibt.


Eingang

Alle Eingänge besteht aus v, >, <, ^, Leerzeichen, und eine einzige X.

Sie können Folgendes annehmen:

  • Die Karte wird sich niemals selbst schleifen oder kreuzen

  • Der Startpfeil ist immer das unterste Zeichen in der Spalte ganz links

  • es wird immer einen Schatz geben ( X)

Eine Beispieleingabe ist unten dargestellt.

  >>v   >>>>>>v
  ^ v   ^     v
  ^ v   ^   v<<
  ^ v   ^   v
  ^ >>>>^   >>X
  ^
>>^

Ausgabe

Die Ausgabe sollte eine durch ", "Grenzen begrenzte Zeichenfolge sein. Unten ist die korrekte Ausgabe der obigen Karte.

E2, N6, E2, S4, E4, N4, E6, S2, W2, S2, E2

Eine einzelne nachfolgende Newline oder ein Leerzeichen ist zulässig.


Beispiele

In:
>>>>>>>>>>>>>>>v
               v
               v
               >>>>X

Out:
E15, S3, E4

In:
>>>>>>v
^     v
^     >>>>X

Out:
N2, E6, S2, E4

In:
X
^
^
^

Out:
N3

In:
>>>>>>v
^     v
^     v
      v
      >>>>>>X

Out:
N2, E6, S4, E6

In:
 X
 ^
 ^
>^

Out:
E1, N3

In:
>X

Out:
E1

In:
v<<<<<
vX<<<^
>>>>^^
>>>>>^

Out:
E5, N3, W5, S2, E4, N1, W3

Glückliches internationales Gespräch wie ein Piratentag!

Zach Gates
quelle
Möglicherweise möchten Sie ein Beispiel einfügen, in dem mehr als ein nach rechts zeigender Pfeil in der Spalte ganz links vorhanden ist, dh in dem der Pfad zurück in die erste Spalte führt. In diesem Fall ist es etwas schwierig, den Anfang des Pfades zu identifizieren.
Reto Koradi
Ich habe ein Beispiel für Ihre Anfrage hinzugefügt. Ich habe auch das Detail hinzugefügt, dass das Startzeichen das unterste der Spalte sein wird. @ RetoKoradi
Zach Gates
Da ich in der verwandten Frage zur Länge des letzten Abschnitts einige Bedenken geäußert habe, werde ich noch einmal nicht picken und sagen, dass dies hier nicht genau die umgekehrte Frage ist. Jemand versucht noch einmal, die Piraten auszutricksen, denkt ich.
Coredump
Der einzige Unterschied ist die Schrittzahl der letzten Richtung. @coredump Zumindest soweit ich das beurteilen kann.
Zach Gates
1
@ZachGates Ja, genau (und um ganz klar zu sein, ich sage nicht, dass die Frage geändert werden sollte, sie ist gut, wie sie derzeit ist).
Coredump

Antworten:

3

CJam, 78 Bytes

qN/_:,$W=:Tf{Se]}s:U,T-{_U="><^vX"#"1+'E1-'WT-'NT+'S0"4/=~_@\}g;;]e`{(+}%", "*

Probieren Sie es online aus .

Erläuterung

Die Hauptidee hier ist, die längste Zeile zu finden (wir nennen diese Länge T), dann alle Zeilen auf die gleiche Länge aufzufüllen und sie zu verketten (diese neue Zeichenfolge ist U). Auf diese Weise wird nur ein einziger Zähler benötigt, um sich in der Karte zu bewegen. Addieren / Subtrahieren 1bedeutet, sich in derselben Zeile nach rechts / links zu Tbewegen. Addieren / Subtrahieren bedeutet, sich eine Zeile nach unten / oben zu bewegen.

qN/    e# Split the input on newlines
_:,    e# Push a list of the line lengths
$W=:T  e# Grab the maximum length and assign to T
f{Se]} e# Right-pad each line with spaces to length T
s:U    e# Concatenate lines and assign to U

Jetzt ist es Zeit, die Schleife einzurichten.

,T-    e# Push len(U) - T
       e# i.e. position of first char of the last line
{...}g e# Do-while loop
       e# Pops condition at the end of each iteration

Der Schleifenkörper verwendet eine Nachschlagetabelle und eine Auswertung, um auszuwählen, was zu tun ist. Zu Beginn jeder Iteration ist das oberste Stapelelement die aktuelle Position. Darunter befinden sich alle verarbeiteten NSWE-Anweisungen. Am Ende der Iteration wird die neue Richtung unter der Position platziert und eine Kopie davon wird als Bedingung für die Schleife verwendet. Zeichen ungleich Null sind wahr. Wenn ein X angetroffen wird, wird 0 als Richtung gedrückt, wodurch die Schleife beendet wird.

_U=      e# Push the character in the current position
"><^vx"# e# Find the index in "><^Vx"
"..."4/  e# Push the string and split every 4 chars
         e# This pushes the following list:
         e# [0] (index '>'): "1+'E" pos + 1, push 'E'
         e# [1] (index '<'): "1-'W" pos - 1, push 'W'
         e# [2] (index '^'): "T-'N" pos - T, push 'N'
         e# [3] (index 'v'): "T+'S" pos + T, push 'S'
         e# [4] (index 'X'): "0"    push 0
=~       e# Get element at index and eval
_@\      e# From stack: [old_directions position new_direction]
         e# To stack: [old_directions new_direction position new_direction]
         e# (You could also use \1$)
         e# new_direction becomes the while condition and is popped off

Jetzt sieht der Stapel folgendermaßen aus : [directions 0 position]. Lassen Sie uns die Ausgabe generieren.

;;    e# Pop position and 0 off the stack
]     e# Wrap directions in a list
e`    e# Run length encode directions
      e# Each element is [num_repetitions character]
{     e# For each element:
 (+   e#   Swap num_repetitions and character
}%    e# End of map (wraps in list)
", "* e# Join by comma and space
Andrea Biondo
quelle
3

CJam, 86 Bytes

qN/_,{1$=cS-},W=0{_3$3$==_'X-}{"^v<>"#_"NSWE"=L\+:L;"\(\ \)\ ( )"S/=~}w];Le`{(+}%", "*

Probieren Sie es online aus

Erläuterung:

qN/     Get input and split into rows.
_,      Calculate number of rows.
{       Loop over row indices.
  1$=     Get row at the index.
  c       Get first character.
  S-      Compare with space.
},      End of filter. The result is a list of row indices that do not start with space.
W=      Get last one. This is the row index of the start character.
0       Column number of start position. Ready to start tracing now.
{       Start of condition in main tracing loop.
  _3$3$   Copy map and current position.
  ==      Extract character at current position.
  _'X-    Check if it's the end character `X.
}       End of loop condition.
{       Start of loop body. Move to next character.
  "^v<>"  List of directions.
  #       Find character at current position in list of directions.
  _       Copy direction index.
  "NSWE"  Matching direction letters.
  =       Look up direction letter.
  L\+:L;  Append it to directions stored in variable L.
  "\(\ \)\ ( )"
          Space separated list of commands needed to move to next position for each of
          the 4 possible directions.
  S/      Split it at spaces.
  =       Extract the commands for the current direction.
  ~       Evaluate it.
}w      End of while loop for tracking.
];      Discard stack content. The path was stored in variable L.
Le`     Get list of directions in variable L, and RLE it.
{       Loop over the RLE entries.
  (+      Swap from [length character] to [character length].
}%      End of loop over RLE entries.
", "*   Join them with commas.
Reto Koradi
quelle
2

Javascript (ES6), 239 Bytes

a=>(b=a.split`
`,b.reverse().some((c,d)=>c[0]!=' '&&((e=d)||1)),j=[],eval("for(g=b[e][f=0];b[e][f]!='X';g=b[e][f],j.push('NSEW'['^v><'.indexOf(i)]+h))for(h=0;g==b[e][f];e+=((i=b[e][f])=='^')-(i=='v'),f+=(i=='>')-(i=='<'),h++);j.join`, `"))

Erläuterung:

a=>(
    b = a.split('\n'),
    // loops through list from bottom to find arrow
    b.reverse().some(
        (c, d)=>
            // if the leftmost character is not a space, saves the index and exit
            // the loop
            // in case d == 0, the ||1 makes sure the loop is exited
            c[0] != ' ' && ((e = d) || 1)
    ),
    j = [], // array that will hold the instructions
    eval("  // uses eval to allow a for loop in a lambda without 'return' and {}

        // loops through all sequences of the same character
        // e is the first coordinate of the current character being analyzed
        // f is the second coordinate
        // defines g as the character repeated in the sequence
        // operates on reversed b to avoid using a second reverse
        // flips ^ and v to compensate

        for(g = b[e][f = 0];
            b[e][f] != 'X'; // keep finding sequences until it finds the X
            g = b[e][f],    // update the sequence character when it hits the start of a
                            // new sequence
            j.push('NSEW'['^v><'.indexOf(i)] + h)) // find the direction the sequence is
                                                   // pointing to and add the
                                                   // instruction to j

            // loops through a single sequence until it hits the next one
            // counts the length in h
            for(h = 0;
                g == b[e][f]; // loops until there is a character that isn't part of
                              // the sequence
                // updates e and f based on which direction the sequence is pointing
                // sets them so that b[e][f] is now the character being pointed toward
                e += ((i = b[e][f]) == '^') - (i == 'v'),
                f += (i == '>') - (i == '<'),
                // increments the length counter h for each character of the sequence
                h++);

            // return a comma separated string of the instructions
            j.join`, `
    ")
)
DankMemes
quelle
0

JavaScript (ES6), 189

Testen Sie das Ausführen des folgenden Snippets in einem EcmaScript 6-kompatiblen Browser.

f=m=>{(m=m.split`
`).map((r,i)=>r[0]>' '?y=i:0);for(x=o=l=k=p=0;p!='X';++l,y+=(k==1)-(k<1),x+=(k>2)-(k==2))c=m[y][x],c!=p?(o+=', '+'NSWE'[k]+l,l=0):0,k='^v<>'.search(p=c);alert(o.slice(7))}

// Testable version, no output but return (same size)
f=m=>{(m=m.split`
`).map((r,i)=>r[0]>' '?y=i:0);for(x=o=l=k=p=0;p!='X';++l,y+=(k==1)-(k<1),x+=(k>2)-(k==2))c=m[y][x],c!=p?(o+=', '+'NSWE'[k]+l,l=0):0,k='^v<>'.search(p=c);return o.slice(7)}


// TEST
out = x => O.innerHTML += x+'\n';

test = 
[[`>>>>>>>>>>>>>>>v
               v
               v
               >>>>X`,'E15, S3, E4']
,[`>>>>>>v
^     v
^     >>>>X`,'N2, E6, S2, E4']
,[`X
^
^
^`,'N3']
,[`>>>>>>v
^     v
^     v
      v
      >>>>>>X`,'N2, E6, S4, E6']
,[` X
 ^
 ^
>^`,'E1, N3']
,[`>X`,'E1']
,[`v<<<<<
vX<<<^
>>>>^^
>>>>>^`,'E5, N3, W5, S2, E4, N1, W3']];

test.forEach(t=>{
  var k = t[1];
  var r = f(t[0]);
  out('Test ' + (k==r ? 'OK' : 'Fail')
      +'\n'+t[0]+'\nResult: '+r
      +'\nCheck:  '+k+'\n');
})
<pre id=O></pre>

Weniger Golf gespielt

f=m=>{
  m=m.split('\n'); // split in rows

  x = 0; // Starting column is 0
  m.forEach( (r,i) => r[0]>' '? y=i : 0); // find starting row

  o = 0; // output string
  p = 0; // preceding character
  l = 0; //  sequence length (this starting value is useless as will be cutted at last step)
  k = 0; //  direction (this starting value is useless as will be cutted at last step)
  while(p != 'X') // loop until X found
  {
    c = m[y][x]; // current character in c
    if (c != p) // changing direction
    {  
      o +=', '+'NSWE'[k]+l; // add current direction and length to output
      l = 0 // reset length
    );
    p = c;
    k = '^v<>'.search(c); // get new current direction
    // (the special character ^ is purposedly in first position)
    ++l; // increase sequence length
    y += (k==1)-(k<1); // change y depending on direction
    x += (k>2)-(k==2); // change x depending on direction
  }
  alert(o.slice(7)); // output o, cutting the useless first part
}
edc65
quelle