> <> Kein Wasser mehr

20

Der geliebte Fisch, der durch den Code von > <> (eine esoterische Programmiersprache) schwimmt , wurde aus seiner natürlichen Umgebung entfernt. Diese Änderung hat es unfähig gemacht, sich in der gewohnten Weise zu bewegen: Was früher eine toroidale Bewegung war, wurde auf eine einfache Bewegung von links nach rechts beschränkt. Aber> <> Programme werden immer noch so geschrieben, als ob der Fisch in der Lage wäre, sie zu durchlaufen. Es ist Ihre Aufgabe, lieber Programmierer, ein Programm zu schreiben, um ein> <> Programm zu linearisieren. Und mach es in so wenigen Bytes wie möglich; Fische haben keine großen Erinnerungen.

Bewegung in> <>

In> <> ist die Bewegung toroidal und erfolgt jeweils zeichenweise. Dies bedeutet, dass der Fisch (der Zeiger) vom Ende einer Linie zurück zum Anfang "herumlaufen" kann. In> <> kann sich der Fisch auch von oben nach unten, von unten nach oben und von rechts nach links bewegen, im Gegensatz zu den meisten Zeigern. Also wäre dieses Bewegungsmuster gültig:

>>>^  >>>v
   >>>^  v

und es würde in einer Endlosschleife enden (zurück zur obersten Zeile, sobald es unendlich über die unterste hinausgeht).

Der Fisch bewegt sich in einem Raster, dessen Länge maximal (Zeilenlänge) und dessen Höhe der Anzahl der Zeilen entspricht.

Wie findest du heraus, in welche Richtung sich der Fisch bewegt? Diese Befehle ändern den Bewegungsvektor (zB (-1,0)bedeutet von rechts nach links):

Command | Direction Change
---------------------------
   >    | (1,0) (default)
   <    | (-1,0)
   ^    | (0,1)
   v    | (0,-1)
   /    | (x,y) -> (y,x)
   \    | (x,y) -> (-y,-x)
   |    | (x,y) -> (-x,y)
   _    | (x,y) -> (x,-y)
   #    | (x,y) -> (-x,-y)
   ;    | (0,0)

Wie bereits erwähnt, bewegt sich der Fisch von links nach rechts, dh mit dem Richtungsvektor (1,0). Der Fisch beginnt mit dem Parsen von Befehlen, beginnend mit dem ersten Befehl, den er sieht, und ändert seine Richtung, wenn ein Befehl mit einem der oben genannten Richtungswechsler übereinstimmt.

Der Fisch bleibt stehen, als er ein sieht ;und beendet das Programm.

Eingang

Die Eingabe ist ein gültiges Programm (z. B. keine Endlosschleife), das über STDIN übergeben wird. Sie können auch eine Datei lesen, wenn Sie möchten. Die Zeilen der einzelnen Programme müssen nicht unbedingt gleich lang sein.

Die Eingabe erfolgt als Zeichenfolge, wobei Zeilenumbrüche jede Zeile im Programm trennen.

Programme werden nicht wiederholt, dh sie werden immer mit einem beendet ;.

Ausgabe

Ausgabe wird das Programm linearisiert. Das heißt, Sie sollten alle Zeichen (einschließlich Richtungswechslern) zurückgeben, die der Fisch sehen würde, wenn das Programm "normal" ausgeführt würde. Dies sind alle Zeichen auf dem Weg zum ;.

Wenn die Eingabe Zeilen ungleicher Länge enthält und der Fisch sich entlang einer Linie bewegt, die kürzer als die Länge der längsten Linie ist, sollten Sie dies so behandeln, als ob sich der Fisch über ein Leerzeichen bewegt (siehe Testfälle).

Wer mit> <> vertraut ist, weiß, dass Richtungswechsler nicht die einzige Möglichkeit sind, Bewegungen auszuführen. Der Einfachheit halber wird die Eingabe so behandelt, als ob sie die einzige Möglichkeit darstellt, Bewegungen zu beeinflussen.

Regeln

  1. Es gelten Standardlücken
  2. Sie können entweder ein vollständiges Programm oder eine Funktion schreiben
  3. Die Eingabe erfolgt über STDIN oder eine Datei als Zeichenfolge, die die durch newlines ( \n) getrennten Programmzeilen enthält.
    • Sie können die Eingabe innerhalb des vorgegebenen Rahmens anders verstehen (zögern Sie nicht, mich zu fragen, ob Sie eine bestimmte Art von Eingabe beabsichtigen). Sie dürfen die Eingabe nicht mit Leerzeichen auffüllen, damit die Zeilenlängen übereinstimmen.
    • Siehe dazu flexiblen Eingabe finden Metapost. Ein allgemeiner Konsens ist aus heutiger Sicht im Rahmen des Zumutbaren so flexibel wie möglich zu gestalten.
  4. Die Ausgabe ist eine einzelne Zeichenfolge über STDOUT oder wird von der Funktion zurückgegeben (je nachdem, was Sie tun möchten, siehe Regel 2).

Testfälle

v     >v
>abcv//;
gfed<^ih

v>abcv<defghi^//>v;



v     >v
>abcv//;
gfed<^

v>abcv<defg  ^//>v;


abcdef;

abcdef;


abcd|;

abcd|dcba;


abcd#;

abcd#dcba;


abcd\;
    _

abcd\_\dcba;


^;
>abcde/
 ^jihg<

^ >abcde/ <ghij^a;


;

;
cole
quelle
2
Können wir die Eingabe als ein Array von Zeichenfolgen verwenden?
Luke
2
Können wir davon ausgehen, dass das erste Zeichen (oben links) kein Semikolon ist?
Kritixi Lithos
1
@KritixiLithos gute Frage, ich werde sagen, das kannst du nicht annehmen. Ich werde einen Testfall hinzufügen.
Cole
1
@Luke Sie können die Eingabe als ein Array von Zeichenfolgen verwenden, wenn es sehr schwierig oder unmöglich ist, das Eingabeformat zu bearbeiten (Zeichenfolge mit durch Zeilenumbrüche getrennten Zeilen). Siehe die jetzt hinzugefügte Regel 3.
Cole
3
Obligatorische upvote für absurde Begründung
Patrick Roberts

Antworten:

13

Röda , 405 393 392 391 371 366 361 236 234 232 230 223 200 Bytes

F f{L=f()|[#_]|sort|tail
c=""x=0
y=0
X=1
Y=0{l=f[y]l.=[" "]*(L-#l)c=l[x]a=X
[c]
C=indexOf(c,`><v^/\|_#`)X=[1,-1,0,0,-Y,Y,-X,X,-X,X][C]Y=[0,0,1,-1,-a,a,Y,-Y,-Y,Y][C]x+=X
x=x%L
y+=Y
y=y%#f}until[c=";"]}

Probieren Sie es online!

Ausgänge prüfen!

Erklärung (veraltet)

F f{                          /* Declares a function F with parameter f */
                              /* Takes a 2D array of single-char Strings as f */
L =                           /* L contains the value of the length of the longest line*/
    f()                       /* Push the contents each element of f to the stream; this pushes each line*/
        | [#_]                /* Pull a line and push its length to the stream*/
               |sort|tail     /* Sort it and get the last value (the largest one) */
c=""                          /* c contains the value of the current char that is being processed */
x=0; y=0                      /* x and y contain the position of the fish */
X=1; Y=0                      /* X and Y contain the direction of the fish */
{ ... }while [c != ";"]       /* While c is not `;` do: */
l=f[y]                        /*  l is the line (row) the fish is at */
c=" " if [x >= #l]            /*  If x is more than or equal to the line's length, set c to a space (so that we don't need to pad spaces to the array at the beginning)*/
else c = l[x]                 /*  Else set c to the character a position x of l*/
[c]                           /*  Push c to the output stream; ie prints c without a trailing newline*/
a = X                         /*  a preserves the value of X before analysing c */
C = indexOf(c,`><v^/\|_#`)    /*  Simple enough */
X=[1,-1,0,0,-Y,Y,-X,X,-X,X][C]/*  Map each value of C to their respective X-direction in the array */
                              /*  If c cannot be found in `><v^/\|_#` then it will be given the value of -1, or in other words, the -1th element of an array its last element */
Y=[0,0,1,-1,-a,a,Y,-Y,-Y,Y][C]/*  Do the same thing for Y */
x += X                        /*  Change the x-pos by the X-direction */
x = x%L                       /*  Wrap around the right edge */
y += Y                        /*  Do the same for y */
y=y%#f                        /*  But wrap around the bottom instead */
x+=L if[x<0]                  /*  Wrap around the left */
y+=#f if[y<0]                 /*  Wrap around the top */
}

Bearbeitungen

  • Dank @fergusq werden 10 Bytes gespart, indem %überprüft wird, ob x oder y die Grenzen überschreiten. Dies ebnete den Weg für weitere 2 Bytes !
  • Wird `\`anstelle von verwendet"\\"
  • In c=""die zweite Zeile verschoben und die darauf folgende neue Zeile entfernt
  • Konvertierung der Zeilen in Einzelzeichenarrays in die Schleifen statt am Anfang verschoben (inspiriert von der Python-Antwort)
  • Verwendete die Klammer-Syntax von while(danke an @fergusq für das Erkennen)
  • Bewegt , um die a=Xaus den if-Aussagen
  • Vielen Dank an @fergusq, dass Sie einen kürzeren Weg gefunden haben, um die Länge der längsten Linie zu ermitteln
  • Verwendete Array-Syntax anstelle von if-Anweisungen (wie die Python-Antwort), um Tonnen von Bytes zu sparen
  • Der Code, der Leerzeichen auffüllte, wurde entfernt. Stattdessen werden Leerzeichen hinzugefügt, wenn sich das> <> bewegt
  • Es wurde ein Fehler behoben, bei dem dank @fergusq ein Charakter golfen wurde
  • Der +1am Ende stehende indexOfund restrukturierte Code wurde entfernt, um 2 Bytes zu sparen
  • 2 Bytes durch Verschieben eingespart (nochmals danke an @fergusq)
  • 1 Byte dank @fergusq mit einer anderen Methode zum Auffüllen von Leerzeichen eingespart
  • 1 Byte mit until[c=";"]anstelle von gespeichertwhile[c!=";"]
  • Dank eines Hinweises von @fergusq entfernte ich die Schleife, die Leerzeichen auffüllt, und ersetzte sie durch l.=[" "]*L
  • Mehr als 20 Bytes wurden gespart, indem die if-Anweisungen am Ende entfernt wurden, die das Programm am linken und oberen Rand umschließen
Kritixi Lithos
quelle
Ich denke, Sie können ein paar Bytes sparen, indem Sie x=((x+X)%#l)anstelle von x+=X. Kommt leider (-1)%#lnoch zurück -1.
Fergusq
@fergusq Golfed Ihren Vorschlag :)
Kritixi Lithos
Sie können es mit nutzen yzu: y=y%#f.
Fergusq
@fergusq War gerade dabei, das hinzuzufügen :)
Kritixi Lithos
Ich habe darüber mehr nachgedacht, hier sind zwei weitere Golftipps: Verwenden keyanstelle von cmpund Verwenden {...}while[...]anstelle von while[...]do ... done.
Fergusq
10

Python 2, 262 243 237 235 234 233 231 221 219 218 217 Bytes

Übernimmt die Eingabe als ['<line_1>', '<line_2>', ...]

i=input()
q=max(map(len,i))
i=[k+' '*q for k in i]
x=y=k=0
j=1
o=''
while';'not in o:r=[1,-1,-j,-k,0,0];o+=i[y][x];l='><#\\v^/|_'.find(o[-1]);a=(r+[k,-j,j])[l];k=([k,-k,k,j]+r)[~l];j=a;x=(x+j)%q;y=(y-k)%len(i)
print o

Probieren Sie es online!

-19 Bytes dank @math_junkie
-6 Bytes dank @ThisGuy
-2 Bytes durch Extrahieren max(map(L,i))in eine Variable (weil sie theoretisch zweimal verwendet wird).
-1 Byte durch Verringern der Anzahl der i[y][x]Auftritte.
-1 Byte mit, '\x00'damit ich nicht den [1:]Teil o[1:]der Ausgabe mit
-2 Byte \0anstelle von \x00
-10 Byte erledigen muss, dank @KritixiLithos, um zu erkennen, dass ich auf der rechten Seite so viel auffüllen kann, wie ich will, weil der extra wird ignoriert
(keine Byte-Änderung). Behobener Fehler, da die extrahierte Variable außerhalb der Schleife
-2 Byte lag, da ich jetzt nur len2-mal verwende. Das erneute Zuweisen benötigt 2 zusätzliche Bytes
-2 Byte, while';'not in oanstattwhile o[-1]!=';'und verwendeno=''statt o='\0'. Dies spart nicht nur 2 Bytes, sondern beseitigt auch das führende Null-Byte, das technisch nicht wirklich gültig war.

Erläuterung

i = input()                       # Takes input as an array of strings
q = max(map(len,i))               # Finds the width of the longest line
i = [k + ' ' * q for k in i]      # Makes sure everything is at least that width
x = y = k = 0                     # Set the point to (0, 0). Set the vertical motion to 0
j = 1                             # Set the horizontal motion to 1
o = '\0'                          # Initialize the output to a null byte (this is output as nothing, so it doesn't actually affect output)
while o[-1] != ';':               # While the last character in the output is not ';' (this is why the output needs to be initialized with something, otherwise o[-1] gives an index error)
    r = [1,-1,-j,-k,0,0]          # Some of the vertical and horizontal coordinates correspond in opposite order
    o += i[y][x]                  # Add the current character to the output
    l = '><#\\v^/|_'.find(o[-1])  # Find the index of the current character here (or -1 if it's just a regular character)
    a = (r + [k, -j, j])[l]       # The fancy array contains the horizontal movement for each control character
    k = ([k, -k, k, j] + r)[~l]   # The fancy array contains the vertical movement for each control character. Using ~l to get the right index, because r has the values backwards
    j = a                         # a was a placeholder because otherwise k would not be correct
    x = (x + j) % q               # Adjust the pointer position
    y = (y - k) % len(i)          # Adjust the pointer position
print o                           # Print the output after the loop is finished
HyperNeutrino
quelle
Sie können Golf aus dem tryseit findRückkehr, -1wenn nicht gefunden: TIO
Math Junkie
@math_junkie Oh okay, danke!
HyperNeutrino
Sie können leneiner Variablen z. B. L3 Bytes und weitere 4 Bytes zuweisen , indem Sie die Mehrzeilenzuordnung 0in 1 Zeile ändern x=y=k=0.
Caird Coinheringaahing
@ThisGuy Danke!
HyperNeutrino
2
@Cole In meinem vorgeschlagenen Golf habe ich j und k am Ende jedes Arrays hinzugefügt. Dies ist, damit die Richtung beibehalten wird
Math Junkie
5

Ruby, 274 200 187 183

Sie haben nur ein paar weitere Zeichen durch Ablegen des Impuls-Arrays entfernt d.

Ich bin ziemlich stolz auf diesen. Das hat Spaß gemacht! Es nimmt ein Array von Zeichenfolgen auf und gibt die richtige Zeichenfolge zurück.

->a{o,x,y='',-1,0
b,m=1,0
(o+=n=a[y=(y+m)%a.size][x=(x+b)%(a.map &:size).max]||' '
b,m=([1]+[0,-1,0]*2+[1,-m]+[-b,m,b]*2+[-m,-b,-m,b,m])[2*('><^v/\\|_#'.index(n)||9),2])until o[?;]
o}

Unten kommentiert.

->a{
    o,x,y='',-1,0  # o is the output string, x and y are the positions in the array
    b,m=1,0          # b and m are the direction of momentum
    until o[?;] # until o contains a semicolon
        w=(a.map &:size).max # w is the max width of the arrays
        h=a.size    # h is the height of arrays
        x=x+b % w   # increment cursor position
        y=y+m % h
        o+=n=a[y][x]||' ' # add the new char (or " ") to o
        ix=2*('><^v/\\|_#'.index(n)||9) # find the index new char in the string
        b,m=([1]+[0,-1,0]*2+[1,-m]+[-b,m,b]*2+[-m,-b,-m,b,m])[ix,2] # set momentum to its new value
    end
    o # return output string
}
Nicht dieser Charles
quelle
1

PHP 7, 291 260 Bytes

for($m=max(array_map(strlen,$z=explode("
",$argv[1]))),$y=0,$r=count($z)-$v=1;';'!=$c;[$v,$w]=[[$v,1,-1,0,0,-$w,$w,-$v,$v,-$v][$o=strpos(' ><^v/\|_#',$c)],[$w,0,0,-1,1,-$v,$v,$w,-$w,-$w][$o]],$x+=$m+$v,$x%=$m,$y=0<=($y+=$w)?$r<$y?:$y:$r)echo$c=$z[$y][$x]??' ';
Chocochaos
quelle
Ich zähle 291 Bytes / Zeichen.
HyperNeutrino
Sie haben
Recht
Hah Mach dir keine Sorgen, das habe ich auch getan.
HyperNeutrino
Ich fand einige Dinge zum Golfen und reduzierte diese um 25% auf 218 Bytes. Nicht getestet, aber auf jeden Fall einen Blick wert .
Titus
2
Ein Fehler in einem meiner Golfplätze und sechs weitere Bytes Golf: aktualisierte Golfliste .
Titus
1

JavaScript, 242 236 235 231 220 Bytes

a=>{n=a.length;m=x=y=p=0;a.map(g=>m=(w=g.length)<m?m:w);q=1,o="";while((t=a[y][x]||" ")!=";")o+=t,h=q,q=[q,1,0,p,-q][(s=">v\\| <^/_#".indexOf(t)+1)%5]*(r=s>5?-1:1),p=[p,0,1,h,p][s%5]*r,x=(x+q+m)%m,y=(y+p+n)%n;return o+t}

Probieren Sie es online!

fəˈnəˈtɛk
quelle
Sie können 13 Zeichen sparen, wenn Sie die Zeichenfolge als Array aufnehmen. Die technischen Daten wurden geändert.
Nicht dass Charles