Zeichne meine Schrägstriche


60

Als Programmierer haben Sie wahrscheinlich von Schrägstrichen und umgekehrten Schrägstrichen gehört. Aber haben Sie von Downslashes gehört? Dann nimmst du ein paar Schrägstriche, verbindest ihre Enden und ziehst sie nach unten.

Für die heutige Herausforderung müssen Sie ein Programm oder eine Funktion schreiben, die eine Zeichenfolge verwendet, die nur aus Schrägstrichen besteht, und alle diese Schrägstriche in einer Linie ausgibt, die sie verbindet. Dies wird viel deutlicher, wenn Sie ein Beispiel sehen. In Anbetracht der Zeichenfolge \\\//\/\\sollten Sie Folgendes ausgeben:

\
 \
  \
  /
 /
 \
 /
 \
  \

Hier einige Erläuterungen:

  • Es muss ein Schrägstrich pro Zeile stehen.

  • Die erste Zeile enthält 0 führende Leerzeichen.

  • Für jedes Paar Schrägstriche:

    • Wenn sie sich unterscheiden, werden sie in derselben Spalte gezeichnet. Zum Beispiel \/wird geben:

      \
      /
      
    • Wenn sie den gleichen Charakter, die untere werden , ist in der Richtung darauf zu, daß für einen umgekehrten Schrägstrich nach rechts bewegt, und für einen Schrägstrich nach links bewegt. So \\//wird es geben

      \
       \
       /
      /
      
  • Jede Zeile kann zusätzliche Leerzeichen enthalten, solange dies das Erscheinungsbild der Ausgabe nicht verändert. Bis zu einer nachgestellten und führenden Zeile ist ebenfalls zulässig. Zusätzliche führende Leerzeichen sind nicht zulässig !

Um dies zu vereinfachen, können Sie davon ausgehen, dass die Zeichenfolge niemals zu viele Schrägstriche enthält. Mit anderen Worten, kein Präfix der Eingabe enthält mehr Schrägstriche als umgekehrte Schrägstriche, sodass eine Eingabe wie \\////oder //niemals gegeben wird. Dies bedeutet auch, dass jede Eingabe mit einem Backslash beginnt.

Wenn Ihre Eingabe als String-Literal interpretiert wird, können Sie die Backslashes umgehen, falls dies erforderlich ist. Sie müssen auch niemals eine Eingabe verarbeiten, die leer ist oder andere Zeichen als Schrägstriche enthält.

Sie können in jedem vernünftigen Format ausgeben .

Wie üblich handelt es sich hierbei um eine Herausforderung. Versuchen Sie daher, die kürzestmögliche Lösung zu finden, auch wenn Sie eine Sprache auswählen, in der dies schwierig ist. Bonuspunkte für die Erklärung interessanter Techniken, mit denen Sie Bytes abgelegt haben!

Beispiele

#Input
\\\\\\\\\\\

#Output
\
 \
  \
   \
    \
     \
      \
       \
        \
         \
          \

#Input
\\\//\\/\//\\///

#Output
\
 \
  \
  /
 /
 \
  \
  /
  \
  /
 /
 \
  \
  /
 /
/


#Input
\/\/\/

#Output
\
/
\
/
\
/

9
Die Backslashes sorgen für eine nervige Menge von entkommen lol ...
totalhuman

Antworten:


20

GNU Sed, 20

s|\\|&^L|g
s|/|^H/^L^H|g

Beachten Sie, dass es sich bei ^Lund ^Hum Literalformfeed- und Backspace-Zeichen (0x12 und 0x8) handelt.

Diese Antwort funktioniert durch Bewegen des Cursors mit Rücktaste und Formfeed-Zeichen. Die Schrägstriche / Backslashes werden nicht mit Leerzeichen aufgefüllt - Nicht sicher, disqualifiziert diese Antwort. Dies funktioniert nicht in TIO, aber es sieht gut aus unter gängigen Terminals wie xtermund gnome-terminal.

Erstellen Sie dieses sed-Skript wie folgt neu:

base64 -d <<< c3xcXHwmDHxnCnN8L3wILwwIfGc= > downslash.sed

Führen Sie es wie folgt aus:

$ echo '\\\//\/\\' | sed -f downslash.sed
\ 
 \ 
  \ 
  /
 /
 \ 
 /
 \ 
  \ 

$ 

Erläuterung:

s|\\|&^L|g     # move cursor down after every "\"
s|/|^H/^L^H|g  # move cursor left before every "/", then after, down and left again

14

Kohle , 13 12 11 Bytes

FS¿⁼ι/↓¶/↘ι

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Unterstützt zusätzliche //s. Erläuterung:

 S              Input string
F               Loop over each character
  ¿             If
    ι           Current character
   ⁼            Equals
     /          Literal /
      ↓¶        Move left
      ↓ /       Print a / downwards
         ↘ι     Else it's a \ so print that down and right

Ich denke, dass ↓¶= "Nach links bewegen" in der Beschreibung nicht richtig ist.
Jonathan Allan

@JonathanAllan Das ist richtig (Zeilenumbruch nach unten gedruckt = nach links verschieben), obwohl es wahrscheinlich klarer wäre, "nach \n/unten drucken " zu sagen
ASCII

Ich habe es nicht gesagt, print \n/ downweil ich der Meinung war, dass es hilfreicher ist, die Wirkung des Codes zu beschreiben, als seine wörtliche Übersetzung.
Neil

1
(Zunge in der Wange: Beschreibung der Wirkung = MyCode - Do the spec). Ich verstehe es jetzt, obwohl der Effekt darin besteht, sich nach links zu bewegen. Es könnte sich lohnen zu sagen "Nach links bewegen (durch Drucken einer neuen Zeile mit Druckrichtung nach unten)".
Jonathan Allan

Am übersichtlichsten und selbsterklärendsten von allen!
J4hangir


10

/// 119 Bytes

/// hat keine Eingabebefehle, daher muss die Eingabe in das Programm eingebettet sein. In diesem Fall wird die Eingabezeichenfolge einfach angehängt, ohne dass ein Escapezeichen erforderlich ist.

/=/\/\///M/
|%%=N/%|||=C/BA=\/\\/\/C\\=C\\/CbC=B\A\=CfC=AB=/A/%Mxy=B/|z%N|x|y% %N%x|y%%% |fzN%M%b|zN|M|%
=|/AB\\=%/|=AC

Wie es funktioniert

  • Im Folgenden \\/\//wird zu Demonstrationszwecken eine Eingabe von an das Programm angehängt.
  • wird verwendet, um Zeilenumbrüche im Inline-Code darzustellen.

Abkürzungen

Der Beginn /=/\/\///M/␤|%%=N/%|||=C/BA=des Programms enthält Substitutionen für Golfabkürzungen.

  • =erweitert sich zu //, Mzu ␤|%%, Nzu %|||und Czu BA.
  • Danach wird das aktuelle Programm

    /\/\\/\/BA\\//BA\\/BAbBA//B\A\//BAfBA//AB///A/%
    |%%xy//B/|z%%||||x|y% %%|||%x|y%%% |fz%|||%
    |%%%b|z%||||
    |%%|%
    //|/AB\\//%/|//ABA\\/\//
    

Eingabe-Rekodierung

In der nächsten Stufe wird die angehängte Eingabezeichenfolge in eine benutzerfreundlichere Form umgewandelt. Da es vollständig aus den beiden Befehlszeichen von /// besteht, ist darauf zu achten, dass das Basisprogramm nicht beschädigt wird.

  • Die erste wesentliche Ersetzung /\/\\/\/BA\\/ersetzt die Zeichenfolge /\durch /BA\.
    • Das Basisprogramm enthält /\zu diesem Zeitpunkt keine, daher wirkt sich diese Ersetzung nicht auf das Programm aus.
    • Dies teilt jedoch die angehängte Eingabezeichenfolge in Folgen von \s gefolgt von Folgen von /s auf, was es zusammen mit dem ABAam Ende des Basisprogramms ermöglicht, sie mit den folgenden Ersetzungen zu durchlaufen.
    • Wenn Sie das ABAPräfix davor einfügen, wird die Beispiel-Eingabezeichenfolge jetzt zu ABA\\/BA\//.
  • Die nächste Substitution, /BA\\/BAbBA/ersetzt BA\durch BAbBA.
    • Da /// Ersetzungen so lange wiederholt werden, bis sie nicht mehr übereinstimmen, durchläuft dies alle \s der Eingabezeichenfolge, die nun mit dem Präfix versehen wirdABAbBAbBA/BAbBA//
  • In ähnlicher Weise /B\A\//BAfBA/ändert sich BA/zu BAfBAund durchläuft das /s.
    • Das Entkommen \bei dieser Substitution ist erforderlich, da es sonst durch die vorherige entstellt würde.
    • Der Eingang hat sich nun in verwandelt ABAbBAbBAfBABAbBAfBAfBA.
  • Als nächstes werden /AB//einige überflüssige Teile der Codierung entfernt und in umgewandelt AbBAbBAfBAbBAfBAfBA.
    • Dies entfernt auch eine ABaus der /|/AB\\/Ersetzung später im Programm, die erforderlich war, um es vor der obigen /\Manipulation zu schützen .
    • Zu diesem Zeitpunkt ist jeder \in der ursprünglichen Eingabezeichenfolge geworden AbB, und jeder /ist geworden AfB. ( bund fstehen für vorwärts und rückwärts.) Am Ende ist ein Streuner A.
  • Die nächsten beiden Ersetzungen ersetzen alle As und Bs durch Programmfragmente, die im Endstadium ausgeführt werden sollen. In den Ersetzungszeichenfolgen codieren %s und |s, was zu /s bzw. \s wird. Dies hat zwei Vorteile:
    • Im Gegensatz zu /und \müssen die %Zeichen s und |s nicht maskiert werden, um kopiert zu werden.
    • Durch die Ersetzungszeichenfolgen wird vermieden /\, dass die Teilzeichenfolge enthalten ist , die andernfalls durch die vorherigen Manipulationen beschädigt worden wäre.
  • Danach entschlüsselt die Substitution /|/\\/(früher /|/AB\\/) nun das |s, woraus das Folgende /%/|//geworden ist /%/\//und das %s entschlüsselt .

Programmstruktur in der Endphase

Zu diesem Zeitpunkt hat das Basisprogramm alle seine Ersetzungen ausgeführt, und alles, was übrig bleibt, ist die Programmcodierung der Eingabezeichenfolge.

  • Jedes eingegebene Zeichen ist zu einem Unterprogramm geworden

    /
    \//xy*\z//\\\\x\y/ //\\\/x\y/// \fz/\\\/
    \///b\z/\\\\
    \//\/
    

    (nachfolgende Newline), wobei *entweder ffür ein Original /oder bfür ein Original steht \.

  • Es gibt auch einen unvollständigen Ersetzungsbefehl /␤\//xyam Ende des Programms, der keine Auswirkung hat, außer einen /für die Ersetzungen des vorherigen Unterprogramms erforderlichen zu liefern .

Geteilte Teilzeichenfolge

Bevor die letzte Iteration durch die Unterprogramme beginnt, befindet sich nach dem Unterprogramm jedes Zeichens des Formulars eine Teilzeichenfolge, die die Grenze überschreitet \/␤/.

  • Diese Teilzeichenfolgen werden als gemeinsam genutzter globaler Status verwendet. Alle verbleibenden Ersetzungen im Programm bearbeiten sie identisch und parallel, so dass am Ende des Unterprogramms jedes Eingabezeichens seine Kopie dieser gemeinsam genutzten Teilzeichenfolge (mit Ausnahme der letzten /, die die Ersetzungen verankert) ausgeführt wird, um die Zeile dafür auszudrucken Charakter.
  • Die anfängliche Version der Teilzeichenfolge stellt das Drucken einer Zeile dar, die nur /die richtige imaginäre "vorherige Zeile" enthält, damit das erste eingegebene Zeichen am Anfang der Zeile gedruckt wird.
  • Im Allgemeinen besteht die gemeinsam genutzte Teilzeichenfolge während der Druckschritte aus einer Reihe von Leerzeichen \\oder \/einer neuen Zeile und einer Folge davon /.

Ausführen eines Zeichenunterprogramms

Einige der folgenden Substitutionen enthalten zusätzliche \s, um zu verhindern, dass sie einander zugeordnet und entstellt werden (einschließlich anderer Kopien in anderen Unterprogrammen). Dies zu erreichen ist auch der Grund, warum sowohl von xals yauch benötigt werden.

  • Die erste Ersetzung in einem Zeichensubprogramm /␤\//xyf\z/oder /␤\//xyb\z/bewirkt, dass ␤/am Ende der gemeinsam genutzten Teilzeichenfolge xyfzoder steht xybz, unmittelbar nach \/oder \\.
  • Die Substitution /\\\\x\y/ /ersetzt \\xydurch ein Leerzeichen, und die Substitution /\\\/x\y//ersetzt \/xydurch nichts.
    • Sie gelten, wenn das zuvor gedruckte Eingabezeichen ein \oder /war.
    • Die gemeinsam genutzte Teilzeichenfolge enthält jetzt die entsprechende Anzahl von Leerzeichen zum Drucken einer \nächsten, gefolgt von fzoder bz.
  • Die Ersetzung / \fz/\\\/␤\//ersetzt ​ fzdurch \/␤/und /b\z/\\\\␤\//ersetzt bzdurch \\␤/.
    • Sie gelten, wenn das aktuelle Eingabezeichen /bzw. \ist.
    • Der erste benötigt einen zusätzlichen Platz, um /richtig zu platzieren.
      • Wenn dieses Leerzeichen fehlt (dh eine Eingabe, die gegen die Präfixbedingung verstößt), werden die folgenden Ersetzungen falsch interpretiert, es wird viel Müll ausgegeben und normalerweise ///eine Endlosschleife getroffen.
    • Jeder fügt den richtigen Befehl hinzu, um sein eigenes Zeichen zu drucken, und stellt das Original ␤/am Ende der freigegebenen Teilzeichenfolge wieder her.
  • Das Zeichen-Unterprogramm hat jetzt seine Kopie der freigegebenen Teilzeichenfolge erreicht, die zum Drucken ihrer Zeile bereit ist.

Nachdem das letzte Zeichen-Unterprogramm ausgeführt wurde, bleibt vom Programm Folgendes übrig /␤\//xy. Da dies eine unvollständige Ersetzung mit fehlendem Finale ist /, wird sie vom Programm übersprungen und normal angehalten.


1
Die richtige Sprache für den Job! Lol
DJMcMayhem

6

Jelly , 14 Bytes

=”\ðḤ’+\_⁸⁶ẋżY

Ein vollständiges Programm druckt das Ergebnis aus.

Probieren Sie es online!

Wie?

=”\ðḤ’+\_⁸⁶ẋżY - Link: list of characters, s    e.g. "\\\//\\/"
 ”\            - literal '\'                         '\'
=              - equal? (call this e)                [1, 1, 1, 0, 0, 1, 1, 0]
   ð           - new dyadic chain f(e, s)
    Ḥ          - double                              [2, 2, 2, 0, 0, 2, 2, 0]
     ’         - decrement                           [1, 1, 1,-1,-1, 1, 1,-1]
      +\       - cumulative reduce with addition     [1, 2, 3, 2, 1, 2, 3, 2]
         ⁸     - chain's left argument, e            [1, 1, 1, 0, 0, 1, 1, 0]
        _      - subtract (# of leading spaces)      [0, 1, 2, 2, 1, 1, 2, 2]
          ⁶    - literal ' '                         ''
           ẋ   - repeat                              [""," ","  "," "," "," ","  ","  "]
            ż  - zip with s                          [["",'\'],[" ",'\'],["  ",'\'],["  ",'/'],[" ",'/'],[" ",'\'],["  ",'\'],["  ",'/']]
             Y - join with newlines                  ["",'\','\n'," ",'\','\n',"  ",'\','\n',"  ",'/','\n'," ",'/','\n'," ",'\','\n',"  ",'\','\n',"  ",'/']
               - implicit print - this smashes the lists (shown as "..." above) and the characters (shown as '...' above) together.



5

JavaScript (ES8), 66 59 63 Bytes

7 Bytes gespart dank Justin Mariner
+4 Bytes zum Reparieren /\\/\\/(von Neil bemerkt )

f=([a,...z],b=a<'0')=>a?a.padStart(b+=k=a>'/')+`
`+f(z,b-!k):''

Probieren Sie es online!


5

MATL , 23 19 18 Bytes

Dank @Sanchises 1 Byte weniger

fGqoEq1yd~h*YsGZ?c

Die Eingabe ist eine Zeichenfolge in einfachen Anführungszeichen.

Probieren Sie es online! Oder überprüfen Sie die Testfälle: 1 , 2 , 3 .

Erläuterung

Betrachten Sie die Eingabe '\\\//\/\\'als Beispiel.

f      % Implicit input. Array of indices of nonzeros. Since all chars in the input
       % have nonzero code point, this gives [1 2 ... n] where n is input length
       % STACK: [1 2 3 4 5 6 7 8 9]
G      % Push input again
       % STACK: [1 2 3 4 5 6 7 8 9], '\\\//\/\\'
qo     % Subtract 1 from (the code-point) of each char and then compute modulo 2.
       % This transforms '\' into 1 and '/' into 0
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 0 0 1 0 1 1]
Eq     % Double, subtract 1. This transforms 0 into -1
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1]
1y     % Push 1 and duplicate from below
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], 1, [1 1 1 -1 -1 1 -1 1 1]
d~     % Consecutive differences, logical negation: gives 1 if consecutive entries
       % are equal, 0 otherwise
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], 1, [1 1 0 1 0 0 0 1]
h      % Horizontally concatenate
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], [1 1 1 0 1 0 0 0 1]
*      % Element-wise multiplication
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 0 -1 0 0 0 1]
Ys     % Cumulative sum
       % STACK: [1 2 3 4 5 6 7 8 9], [1 2 3 3 2 2 2 2 3]
G      % Push input again
       % STACK: [1 2 3 4 5 6 7 8 9], [1 2 3 3 2 2 2 2 3], '\\\//\/\\'
Z?     % Build sparse matrix with those row indices, column indices, and values
       % STACK: [92  0  0;
                  0 92  0;
                  0  0 92;
                  0  0 47;
                  0 47  0;
                  0 92  0;
                  0 47  0;
                  0 92  0;
                  0  0 92]
c      % Convert to char. Char 0 is shown as space. Implicitly display
       % STACK: ['\  ';
                 ' \ ';
                 '  \';
                 '  /';
                 ' / ';
                 ' \ ';
                 ' / ';
                 ' \ ';
                 '  \']

Ein Byte von einem etwas anderen Algorithmus entfernt, um Ihre Indizes zu erhalten: Probieren Sie es online aus!
Sanchises

@Sanchises Vielen Dank für Ihre sehr geeigneten Änderungen!
Luis Mendo

5

C # (.NET Core) , 74 88 82 78 77 76 + 18 Byte

-1 Byte dank Kevin Cruijssen

s=>s.Select((x,i)=>$"{x}".PadLeft((x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)))

Gibt eine Sammlung von Zeichenfolgen aus, eine für jede Zeile. Die Byteanzahl umfasst auch:

using System.Linq;

Probieren Sie es online!

Erklärung für die 77-Byte-Antwort:

s =>                              // Take input, a string
    s.Select((x, i) =>            // Replace every character with:
        $"{x}"                    //     The character as string
        .PadLeft(                 //     Pad with this many spaces:
            s.Take(i)             //         Take characters, in the input string, preceding current one
            .Sum(y =>             //         Sum them by:
                y < 92 ? -1 : 1   //             If it's a \ add 1, if / subtract 1
            )
            + (x - s[0]) / 45 + 1 //         If first slash is a / add one more space, if current slash is a \ add one more space (I got this through power of MATHS!)
                                  //         How I arrived at this function:
                                  //         + x / 48        If current slash is a \ add one more space
                                  //         - s[0] / 48 + 1 If the first slash is a / add one more space
        )
    )

3
Funktioniert nicht für /\\/\\/.
Neil

@Neil danke für den Hinweis! Fest.
Grzegorz Puławski

1
Ich weiß, es ist schon eine Weile her, aber Sie können ein Byte speichern, indem Sie s.Take(i).Sum(y=>y<92?-1:1)+(x-s[0])/45+1auf(x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)
Kevin Cruijssen

Nice one @KevinCruijssen!
Grzegorz Puławski

4

05AB1E , 14 Bytes

ÇÈx<ηOs-W-ISú»

Probieren Sie es online!

Erläuterung

Ç                # convert input string to a list of ascii codes
 È               # check each for evenness
  x              # push a doubled copy
   <             # decrement
    η            # compute prefixes
     O           # sum each prefix
      s          # swap the unaltered copy of evenness to the top
       -         # subtract from the prefix-sum list
        W-       # subtract the minimum value
          IS     # push input split to a list of chars
            ú    # pad each with the number of spaces computed
             »   # join on newline

1
Funktioniert nicht für /\\/\\/.
Neil

Ç¥.¥0<.SηOv¹Nèy<ú, Schluchzen in binären
Magic Octopus Urn

3

R , 122 121 Bytes

-1 Byte danke an Giuseppe

x=el(strsplit(scan(,""),""));n=seq(x);y=x>"/";for(i in n)cat(rep(" ",diffinv(y[n[-1]-1]+y[n[-1]]-1)[i]),x[i],"\n",sep="")

Probieren Sie es online!

Mit zusätzlichem Leerzeichen:

x = el(strsplit(scan(,""),""))
n = seq(x)
y = x>"/"
for(i in n) {
  cat(rep(" ", diffinv(y[n[-1]-1]+y[n[-1]]-1)[i]), x[i], "\n", sep="")
}

Erläuterung: Diese Antwort basiert auf der Beobachtung, dass sich die Anzahl der führenden Leerzeichen in jeder Zeile um -1 ändert, zuzüglich der Anzahl /in der vorherigen und der aktuellen Zeile.

Wenn wir N Schrägstriche haben, ist die Variable yein Vektor der Länge N, \ansonsten 1 für jede Position mit , 0. Daher berechnen wir, um die Änderung der Anzahl der führenden Leerzeichen pro Zeile zu erhalten y[1:(N-1)] + y[2:N] - 1. Die Funktion diffinvkonvertiert diese Differenzen in eine Sequenz, beginnend mit 0. Der Rest ist nur eine Frage der Zusammenstellung jeder Zeile als die erforderliche Anzahl von nachgestellten Leerzeichen, gefolgt von dem entsprechenden Schrägstrich und einer neuen Zeile.


1
huh. Ich habe für 119 Bytes einen ganz anderen Ansatz gewählt, weshalb ich mich frage, ob wir unsere Ansätze kombinieren könnten. (nette Verwendung von diffinv;) Auch Sie können y=x>")"für -1 Byte einstellen
Giuseppe

@ Giuseppe Du solltest das als separate Antwort posten, es ist ein ausreichend anderer Ansatz. Mit freundlichen Grüßen vermeiden Sie das strsplit, was immer tödlich ist. Sie können auch die berühmten nutzen diffinv!
user2390246

1
Ich denke auch, wenn Sie library(methods)in den Header setzen (was ohne Strafe OK sein sollte, da dieses Paket Teil Basis R ist), können Sie verwenden el. Auch stellte diffinvsich heraus, dass es genauso lang ist wie cumsum! :)
Giuseppe

Ja, ich habe das auch nur
gemerkt

Nun, ich habe einen Workaround gefunden , aber das *Sbringt alles durcheinander.
Giuseppe

3

Brain-Flak , 175 Bytes (174 Zeichen + 1 Flag)

Laufen Sie mit -cFlagge.

{(({})<(())>){({}[()]<([{}])>)}{}(({}<>{}<><({}<>)((()()()()()){})>)<{({}[()]<((((()()()()){}){}){})>)}>{})<>}<>{}{({}<>)(({})(())){({}[()]<([{}]())>)}{}{<>{}<>(<{}>)}{}<>}<>

Probieren Sie es online!

Erläuterung

{ for each char in the input...
  (({})<(())>){({}[()]<([{}])>)}{} push 1/-1 for backslash/slash
  ((
   {}<>{}<> add the 1/-1 to a running total
   <
    ({}<>) move slash/backslash to other stack
    ((()()()()()){}) newline
   >
  )<{({}[()]<((((()()()()){}){}){})>)}>{}) spaces
  <>
}<>{} end for
reverse data order, removing one space before backslash
{({}<>)(({})(())){({}[()]<([{}]())>)}{}{<>{}<>(<{}>)}{}<>}<>

Ich habe immer gehirnflockig gestimmt. : D
DJMcMayhem

3

Ruby , 80 76 Bytes

-4 Bytes dank Handarbeit

puts"\\";$*[i=0].chars.each_cons 2{|b,c|puts" "*(b==c ?b==?/?i-=1:i+=1:i)+c}

Probieren Sie es online!

Erläuterung:

puts "\\"           # Output the first backslash
$*[i=0].            # Get the first argument and set i to 0
chars.              # Go through every individual character,
each_cons 2 { |b,c| # In pairs to compare easily
                    #
    puts " " *      # Decide how many padding spaces to use based on the value
                    # of i. The expression inside the parenthesis will return
                    # i but before that, it will increment/decrement i based
                    # on what the previous character was.
                        #
    ( b==c ?            # if b == c
        b==?/ ?         #   if b == "/" (Going to the left)
            i-=1        #       return decremented i
            :           #   else        (Going to the right)
            i+=1        #       return incremented i
        :               # else
        i) +            #   return i
                    #
                c   # Finally, write the second of the characters that we're
}                   # iterating through.

1
Welche Ruby-Version? Die 2.3.3 Ich habe verlangt Klammer um Parameter , wenn Codeblock folgt: .each_cons(2){…}. In Änderung können Sie durch Ersetzen von .each_char→ speichern .chars.
Manatwork

@manatwork Meine Rubin-Version ist 2.4.1. Vielen Dank für den Vorschlag zu Zeichen, von dem ich nichts wusste.
Pazzaz

Sie können weitere zwei Bytes speichern, indem Sie i+=an den Anfang des verschachtelten ternären Ausdrucks springen und ihn mit beenden -1:1:0.
benj2240

3

Java 8, 121 118 110 109 102 Bytes

a->{String r="";int s=0,p=0,i;for(char c:a){for(i=s+=p+(p=c-63)>>5;i-->0;r+=" ");r+=c+"\n";}return r;}

-7 Bytes dank der bitweisen Magie von @Nevay . :)

Erläuterung:

Probieren Sie es hier aus.

a->{                    // Method with char-array parameter and String return-type
  String r="";          //  Return-String
  int s=0,              //  Amount of spaces
      p=0,              //  Previous characters (starting at 0)
      i;                //  Index-integer
  for(char c:a){        //  Loop over the input
    for(i=s+=p+(p=c-63)>>5;
                        //   If the current does not equals the previous character
                        //    Leave `s` the same
                        //   Else-if it's a '\':
                        //    Increase `s` by 1
                        //   Else (it's a '/'):
                        //    Decrease `s` by 1
                        //   And set the previous character to the current in the process
        i-->0;r+=" ");  //   Append `r` with `s` amount of spaces               
    r+=c+"\n";          //   Append the character + a new-line to the result
  }                     //  End of loop
  return r;             //  Return result-String
}                       // End of method

1
102 Bytes:a->{String r="";int s=0,p=0,i;for(char c:a){for(i=s+=p+(p=c-63)>>5;i-->0;r+=" ");r+=c+"\n";}return r;}
Nevay

@Nevay Danke. Ich wusste, dass es mit ein paar bitweisen Operationen verkürzt werden konnte, konnte es aber nicht herausfinden. Hauptsächlich, weil ich vergessen hatte, die Effekte von >>/ >>>/ <<... &|~^
auszuprobieren,

3

C (GCC) 137 134 97 Bytes

Probieren Sie es online!

• 3 Bytes dank ATaco

• 37 Bytes dank Digital Trauma & ThePirateBay

i,d;f(char*s){char c=s[i],n=s[++i];if(c){printf("%*c%c\n",d+1,c);(c-n)?d:(c==47)?--d:++d;f(s);}}

Nichts Besonderes, nur eine einfache rekursive Funktion, die einen String verwendet und die Schrägstriche ausgibt. Beachten Sie, dass die Eingabe zuerst die umgekehrten Schrägstriche überschreiben muss.

Verwendungszweck

f("\\\\\\//\\/\\\\",0,0);

Ungolfed

Dies ist die alte Antwort. Sehen Sie sich den Link online ausprobieren für eine aktualisierte Antwort an!

f(char *s, i, d) {
    char c=s[i], n=s[++i];
    if(!c) return;
    for(int j=0; j<d; j++) printf(" ");
    printf("%c\n",c);
    f(s, i, (c!=n)?d:(c=='/')?d-1:d+1);
}

Ausgabe

Bildbeschreibung hier eingeben


Sie können c=='\0'mit !cfür den gleichen Effekt ersetzen .
ATaco

Ehrfürchtiger Dank hat gerade die Lösung aktualisiert!
Schlafende

Können Sie printf("%*s%c", n, "", c)das Zeichen mit n führenden Leerzeichen drucken?
Digital Trauma

Ich bin mir ziemlich sicher , dass Sie wenige Bytes durch Ersetzen sparen können (c!=n)mit c-nund Neuanordnung ternäre Ausdrücke. Gleiche mit (c=='/'). Sie können auch durch eine '/'Literalnummer ersetzen 47. Ich denke, es sind insgesamt 7 Bytes.



3

Netzhaut , 47 Bytes

^|\\
 $&
+m`^( *)( /|\\)(/| \\)
$1$2¶$1$3
m`^ 

Probieren Sie es online! Link enthält Testfälle. Erläuterung:

^|\\
 $&

Fügen Sie am Anfang jeder Zeile und vor jeder Zeile ein Leerzeichen ein \.

+m`^( *)( /|\\)(/| \\)
$1$2¶$1$3

Betrachten Sie die ersten beiden Zeichen der Zeichenfolge. Wenn der erste ein /ist, muss der Einzug dekrementiert werden. Dies wird erreicht, indem der vorhergehende Bereich in das Capture aufgenommen wird (der immer vorhanden ist, weil die erste Stufe ihn hinzugefügt hat). Wenn die Sekunde eine \\ist, muss sie inkrementiert werden. Dies wird durch Einbeziehen des Speicherplatzes erreicht, den die erste Stufe dem Capture hinzugefügt hat. Nachdem das zweite Zeichen den richtigen Einzug erhalten hat, wird die Stufe für das zweite und dritte Zeichen usw. wiederholt.

m`^ 

Entfernen Sie den zusätzlichen Einzug.

Ich habe eine 94-Byte-Version geschrieben, die (wie meine Charcoal-Antwort) eine beliebige Kombination von Schrägstrichen zulässt: Probieren Sie es online aus! Erläuterung:

.$
¶$.`$* $&

Bringe den Ball ins Rollen, indem du den letzten Schrägstrich nimmst und ihn an derselben Position in seiner eigenen Linie einrückst.

/
 /

Stellen Sie allen Schrägstrichen ein Leerzeichen voran, damit sie erfasst werden können.

+`^(.*)( /|\\)¶( *)( \\|/)
$1¶$3$2¶$3$4

Nehmen Sie wiederholt den letzten Schrägstrich der Eingabe und richten Sie ihn in einer eigenen Zeile an dem Schrägstrich in der Zeile darunter aus.

+ms`^(?<!^[\\/].*) (?!.*^[\\/])

Löschen Sie alle verbleibenden Einrückungen.

G`.

Löschen Sie die jetzt leere Eingabe.


2

Lua , 96 Bytes

c=0 for s in(...):gmatch(".")do c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end

Probieren Sie es online!

Das kürzeste, das ich in Lua finden konnte. Die Eingabe erfolgt über die Befehlszeile.

Dies erfordert einige Tricks:

  1. (...):gmatch(
    Dies sollte die kürzeste Form sein, um einen einzelnen String von der Kommandozeile in ein Lua-Programm zu bekommen. Der ...Ausdruck in Lua erfasst alle überschüssigen Parameter einer Funktion, die nicht in der Funktionsdeklaration angegeben sind, und wird für varargs verwendet. Da der Hauptteil eines Lua-Programms als Funktion mit den Befehlszeilenargumenten als Parametern aufgerufen wird, enden die Befehlszeilenargumente in ....
    Die umgebenden Klammern verwandeln den potenziell mehrwertigen ...Ausdruck in einen einwertigen Ausdruck. Betrachten Sie dieses (etwas überraschende) Beispiel:
    function multipleReturnValues()
        return "abc", "def"
    end
    print(  multipleReturnValues()  ) --This prints: abc    def
    print( (multipleReturnValues()) ) --This prints: abc
  2. Der Lua-Parser benötigt weder Zeilenabschlusszeichen noch Leerzeichen zwischen Anweisungen, solange die Token der beiden Anweisungen klar voneinander getrennt werden können und nur eine Interpretation des Textes vorhanden ist, der gültigen Lua-Code enthält.
  3. Missbrauch and/ orfür "wenn x dann Wert1 sonst Wert2" Logik.
    Der andOperator von Lua gibt das erste Argument zurück, wenn es falsch ist. Andernfalls wird das zweite Argument zurückgegeben. Der orOperator gibt das erste Argument zurück, wenn es wahr ist. ansonsten das zweite Argument.
  4. pbenötigt keine Initialisierung.
    p==smuss im ersten Durchlauf der Schleife immer false sein, unabhängig von der Eingabe. Wenn Sie pvor dem Eintritt in die Schleife (Verlassen der Schleife nil) keinen Wert einstellen, geschieht dies und es werden auch Bytes gespart.

Kann jemand Golf spielen (in Lua)?


Ich konnte zwei Bytes sparen, indem ich gsub anstelle von gmatch verwendete. c=0(...):gsub(".",function(s)c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end)
QuertyKeyboard

Nun, nicht dass es darauf ankommt. Sie hätten leicht zwei Bytes sparen können, indem Sie geändert haben gmatch("."), gmatch"."wie Sie es in Ihrer nächsten Antwort getan haben.
QuertyKeyboard

@QuertyKeyboard Das ist seltsam ... Ich habe gsub in der ersten Version dieses Codes genau so verwendet, dann aber stattdessen auf gmatch umgestellt, weil es irgendwie kürzer geworden ist. Ich weiß aber nicht, was ich anders gemacht habe, die Datei wird leider überschrieben.
Jonathan S.


2

R , 119 Bytes

function(s)for(i in 1:nchar(s))cat(rep(" ",cumsum(c(0,!diff(S<-(utf8ToInt(s)>48)*2-1))*S)[i]),substr(s,i,i),"
",sep="")

Probieren Sie es online!

Dies unterscheidet sich etwas von der Antwort von user2390246 . Sie durchlaufen jeweils die Zeichenfolge und geben eine bestimmte Anzahl von Leerzeichen und dann das entsprechende /\Zeichen aus.

Ich habe jedoch vermieden, die Zeichenfolge zu teilen, und stattdessen die Zeichen durch den UTF-8-Codierungswert ersetzt, sodass ich direkt mit den Zahlen rechnen kann, was mir nur ein paar Bytes erspart hat.


Ich habe nur noch ein
bisschen darüber nachgedacht

@ user2390246 Ich habe es behoben! Ich hatte ein paar falsch gesetzte Klammern, aber jetzt wird das hier diffinvdefinitiv nicht funktionieren.
Giuseppe


2

C # (.NET Core) , 60/65 Byte

Ich habe versucht kürzere C # -Version

s=>{int i=0;return s.Select(x=>"".PadLeft(x<92?--i:i++)+x);}

wie gesagt: "Das bedeutet auch, dass jede Eingabe mit einem Backslash beginnt." Oder etwas länger welche lösen ab "/"

s=>{int i=s[0]&1;return s.Select(x=>"".PadLeft(x<92?--i:i++)+x);}

Probieren Sie es online!


Willkommen auf der Seite! :)
DJMcMayhem

2

Lua , 88 84 Bytes

Verbesserte Version (-4 Bytes dank QuertyKeyboard)

s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)

Probieren Sie es online!

Originalversion (88 Bytes)

Ein weiterer Versuch in Lua, diesmal mit einem völlig anderen Ansatz, bei dem anstelle einer Zählervariablen die Zeichenfolge manipuliert wird.

s=""for c in(...):gmatch"."do s=s:gsub("\\"," "):gsub("/?$",c):gsub(" /","/")print(s)end

Ungolfed:

s = ""
for c in string.gmatch((...), ".") do --for each character in the input
  --s contains the output from the previous iteration
  s = s:gsub("\\", " ") --Replace backslash with space -> indent by 1
  s = s:gsub("/?$", c) --Remove any / at the end of the string and append c to the string
  s = s:gsub(" /", "/") --Remove a single space in front of any / -> un-indent by 1
  print(s)
end

Es gibt eine interessante Sache im Code: (...):gmatch"."
Hier werden einige Macken im Lua-Parser verwendet. Wenn Lua auf einen Code im Formular stößt func "string", wird dieser in konvertiert func("string"). Dies ist so, dass man schreiben kann, print "string"um eine konstante Zeichenfolge zu drucken, und es funktioniert nur mit einem einzelnen Zeichenfolgenliteral nach der Funktion. Alles andere führt zu einem Syntaxfehler. Dieser syntaktische Zucker funktioniert jedoch auch mit Funktionsaufrufen in der Mitte eines Ausdrucks, und überraschendererweise funktioniert er gut mit dem :Methodenaufruf syntaktischer Zucker. Also wird Lua den Code am Ende so interpretieren:

(...):gmatch"."
-> (...):gmatch(".")
-> string.gmatch((...), ".")

Wenn jemand eine Möglichkeit findet, einen der drei gsub-Aufrufe zu entfernen, teilen Sie mir dies bitte mit.


1
Ich war enttäuscht, dass mein gsub-Trick, den ich in deiner anderen Antwort kommentiert habe, für diese nicht ganz funktioniert hat. Tatsächlich wurde ein Byte hinzugefügt. Ich würde jedoch nicht so leicht aufgeben. Zuerst habe ich versucht, gsub als Variable zu speichern, um den Code zu verkürzen. Zu meiner Überraschung hatte mein Code genau die gleiche Anzahl von Bytes - 88. Ich erkannte jedoch, dass mein gsub-Trick jetzt funktionieren könnte, wenn gsub gespeichert wird! Hier ist mein Code, mit dem 4 Bytes s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)
gespart wurden

@QuertyKeyboard Ja, ich habe auch versucht, gsub in einer Variablen vor der Schleife zu speichern und dann zu verwenden, anstatt gsub drei Mal zu schreiben, und ich war genauso überrascht, dass es absolut keinen Unterschied machte. Das Kombinieren der Tricks "gsub anstatt loop" und "store gsub" ist wirklich gut, ich habe nicht daran gedacht! Vielen Dank! :)
Jonathan S.


1

Perl, 40 + 2 Bytes

/\//&&$.--,say($"x$.,$_),/\\/&&$.++for@F

Du brauchst die -FFlagge.


1

Perl, 34 38 + 1 Bytes

die beiden Fälle zu behandeln

s,(/)|.,$"x($1?$c&&--$c:$c++).$&.$/,ge

mit -pOption ausgeführt werden

s,(/)|.,$"x($1?--$c:$c++).$&.$/,ge

BEARBEITEN: Der folgende Kommentar funktioniert nicht, wenn das erste Zeichen ist /

s,(/)|.,$"x($1?$c--:++$c).$&.$/,ge

Die Ausgabe wird jedoch um ein Zeichen nach rechts verschoben, wenn das erste Zeichen steht \


1
Funktioniert nicht für /\\/\\/.
Neil

Mit der aktualisierten Frage ist Ihre ursprüngliche 34Lösung jetzt vollkommen gültig
Ton Hospel

1

VBA (Excel), 181 Bytes

Sub q()
a = Cells(1, 1)
For x = 1 To Len(a)
c = Mid(a, x, 1)
If c = "\" Then: Debug.Print b & c: b = b + " "
If c = "/" Then: b = Left(b, Len(b) - 1): Debug.Print b & c
Next
End Sub

1
Sie können dies erheblich reduzieren, ohne Ihren Algorithmus zu ändern, indem Sie die automatische Formatierung von Excel VBA nutzen und die [...]Notation verwenden: Ich habe es auf 128 Bytes reduziertSub q For x=1To[Len(A1)] c=Mid([A1],x,1) If c="\"Then Debug.?b;c:b=b+" " If c="/"Then b=Left(b,Len(b)-1):Debug.?b;c Next End Sub
Taylor Scott

Danke, dass du mein Drehbuch geschrieben hast. Ich habe etwas daraus gelernt und werde mich in Zukunft bewerben. :) Wusste nicht, dass ich damit Daten direkt in die Zellen holen kann.
Nochmals vielen



Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.