Disegna le mie ciglia


60

Come programmatore, probabilmente hai sentito parlare di barre rovesciate e barre rovesciate. Ma hai sentito parlare di downslash? Questo è quando prendi un sacco di barre, connetti le loro estremità e le trascini verso il basso.

Per la sfida di oggi, è necessario scrivere un programma o una funzione che accetta una stringa costituita esclusivamente da barre e genera tutte quelle barre disegnate verso il basso in una linea che le collega. Questo sarà molto più chiaro se vedi un esempio. Data la stringa \\\//\/\\, dovresti produrre:

\
 \
  \
  /
 /
 \
 /
 \
  \

Ecco alcuni chiarimenti:

  • Deve esserci una barra per riga.

  • La prima riga avrà 0 spazi iniziali.

  • Per ogni coppia di barre:

    • Se sono diversi l'uno dall'altro, verranno disegnati nella stessa colonna. Ad esempio, \/darà:

      \
      /
      
    • Se hanno lo stesso personaggio, quello inferiore è nella direzione indicata , che si sposta verso destra per una barra rovesciata e verso sinistra per una barra. Così \\//darà

      \
       \
       /
      /
      
  • Ogni riga può avere spazi bianchi finali aggiuntivi purché ciò non cambi l'aspetto visivo dell'output. È accettabile anche una riga finale nuova e iniziale. Non sono ammessi spazi iniziali aggiuntivi !

Per mantenerlo più semplice, puoi presumere che la stringa non conterrà mai troppe barre in avanti. In altre parole, nessun prefisso dell'input conterrà più barre rovesciate rispetto alle barre rovesciate, quindi un input simile \\////o //non verrà mai fornito. Questo significa anche che ogni input inizierà con una barra rovesciata.

Se il tuo input viene preso come una stringa letterale, puoi evitare le barre rovesciate se è necessario. Inoltre non dovrai mai gestire un input vuoto o che contiene caratteri diversi da una barra.

È possibile produrre in qualsiasi formato ragionevole .

Come al solito, si tratta di una sfida di , quindi cerca di rendere la soluzione più breve possibile, anche se scegli una lingua in cui è piuttosto difficile. Punti bonus per la spiegazione di eventuali tecniche interessanti che hai usato per eliminare i byte!

Esempi

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

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

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

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


#Input
\/\/\/

#Output
\
/
\
/
\
/

9
Le barre rovesciate creano una fastidiosa quantità di lol in fuga ...
totalmente umano

Risposte:


20

GNU Sed, 20

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

Si noti che ^Le ^Hsono formfeed e backspace caratteri letterali (0x12 e 0x8).

Questa risposta funziona spostando il cursore utilizzando i caratteri backspace e formfeed. Le barre / barre rovesciate non sono riempite a sinistra di spazi - Non sono sicuro che questo squalifica questa risposta. Questo non funziona in TIO, ma sembra perfetto con terminali comuni come xterme gnome-terminal.

Ricrea questo script sed come segue:

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

Eseguilo come segue:

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

$ 

Spiegazione:

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

Carbone , 13 12 11 byte

FS¿⁼ι/↓¶/↘ι

Provalo online! Il collegamento è alla versione dettagliata del codice. Supporta extra //s. Spiegazione:

 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

Penso ↓¶= "Sposta a sinistra" nella descrizione non è giusto.
Jonathan Allan,

@JonathanAllan Esatto (newline stampato in basso = sposta a sinistra), anche se probabilmente sarebbe più chiaro dire "stampa in \n/basso"
solo ASCII il

Non ho detto print \n/ downperché ho ritenuto che fosse più utile descrivere l'effetto del codice piuttosto che la sua traduzione letterale.
Neil,

1
(Lingua nella guancia: descrizione dell'effetto = MyCode - Do the spec). Ora capisco anche se l'effetto è spostarsi a sinistra; potrebbe valere la pena dire "Sposta a sinistra (stampando una nuova riga con una direzione di stampa verso il basso)".
Jonathan Allan,

Più conciso e autoesplicativo di tutti!
J4hangir,


10

/// , 119 byte

/// non ha comandi di input, quindi l'input deve essere incorporato nel programma. Per questo, la stringa di input viene semplicemente aggiunta, senza necessità di escape.

/=/\/\///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

Come funziona

  • Di seguito, un input di \\/\//verrà aggiunto al programma per la dimostrazione.
  • è usato per rappresentare le nuove righe nel codice inline.

Abbreviazioni

L'inizio /=/\/\///M/␤|%%=N/%|||=C/BA=del programma contiene sostituzioni per le abbreviazioni del golf.

  • =si espande in //, Mverso ␤|%%, Nverso %|||e Cverso BA.
  • Dopo questo diventa il programma attuale

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

Ricodifica input

La fase successiva trasforma la stringa di input aggiunta in una forma più utilizzabile. Dato che è costituito interamente dai due caratteri di comando di ///, è necessario fare attenzione a non alterare il programma di base.

  • La prima sostituzione sostanziale /\/\\/\/BA\\/, sostituisce la stringa /\con /BA\.
    • Il programma di base non contiene /\al momento, quindi questa sostituzione non lo influenza.
    • Tuttavia, questo suddivide la stringa di input aggiunta in sequenze di \s seguite da sequenze di /s, che insieme ABAalla fine del programma di base consente di scorrere attraverso di essa con le seguenti sostituzioni.
    • Includendo il ABAprefisso prima di esso, la stringa di input di esempio ora diventa ABA\\/BA\//.
  • La prossima sostituzione /BA\\/BAbBA/, sostituisce BA\da BAbBA.
    • Poiché le sostituzioni /// vengono ripetute fino a quando non corrispondono più, questo scorre attraverso tutte le \s della stringa di input, che con il prefisso ora diventaABAbBAbBA/BAbBA//
  • Allo stesso modo, /B\A\//BAfBA/cambia BA/in BAfBA, iterando attraverso la /s.
    • La fuga \in questa sostituzione è necessaria poiché altrimenti sarebbe alterata dalla precedente.
    • L'input è ora diventato ABAbBAbBAfBABAbBAfBAfBA.
  • Successivamente /AB//rimuove alcune parti superflue della codifica, trasformandola in AbBAbBAfBAbBAfBAfBA.
    • Questo rimuove anche un ABdalla /|/AB\\/sostituzione più avanti nel programma, che era necessario per proteggerlo dalla /\manipolazione di cui sopra .
    • A questo punto tutti \nella stringa di input originale sono diventati AbBe tutti /sono diventati AfB. ( be fsostengono avanti e indietro.) Alla Afine c'è un randagio .
  • I successivi due sostituzioni sostituiscono tutti i As e Bs con frammenti di programma per eseguire nella fase finale. Nelle stringhe di sostituzione, %s e |s codificano ciò che diventerà rispettivamente /s e \s. Questo ha due vantaggi:
    • A differenza di /e \, gli %s e |s non hanno bisogno di scappare per essere copiati.
    • Le stringhe di sostituzione evitano di contenere la sottostringa /\, che altrimenti sarebbe stata alterata dalle precedenti manipolazioni.
  • Dopo questo, la sostituzione /|/\\/(precedentemente /|/AB\\/) ora decodifica la |s, dopo di che /%/|//è diventato il seguente /%/\//e decodifica la %s.

Struttura del programma nella fase finale

A questo punto, il programma di base ha eseguito tutte le sue sostituzioni e tutto ciò che rimane è la codifica del programma della stringa di input.

  • Ogni carattere di input è diventato un sottoprogramma

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

    (newline finale), dove *rappresenta fun originale /o bun originale \.

  • Esiste anche un comando di sostituzione incompleto /␤\//xyalla fine del programma, che non avrà alcun effetto se non quello di fornire un necessario /per le sostituzioni del sottoprogramma precedente.

Sottostringa condivisa

Prima che inizi l'iterazione finale attraverso i sottoprogrammi, c'è una sottostringa che attraversa il confine dopo il sottoprogramma di ciascun personaggio del modulo \/␤/.

  • Queste sottostringhe vengono utilizzate come stato globale condiviso. Tutte le rimanenti sostituzioni nel programma le manipoleranno in modo identico e parallelo, in modo tale che alla fine del sottoprogramma di ciascun personaggio di input /venga eseguita la sua copia di questa sottostringa condivisa (tranne la finale , che fissa le sostituzioni) per stampare la riga carattere.
  • La versione iniziale della sottostringa rappresenta la stampa di una riga contenente just /, che è la giusta "riga precedente" immaginaria per causare la stampa del primo carattere di input all'inizio della riga.
  • In generale, durante le fasi di stampa, la sottostringa condivisa è costituita da un numero di spazi, \\o da \/una nuova riga e da un seguito /.

Esecuzione di un sottoprogramma di caratteri

Diverse delle seguenti sostituzioni contengono ulteriori messaggi di testo \all'interno per impedire che vengano accoppiati e alterati l'uno dall'altro (comprese altre copie in altri sottoprogrammi). Il raggiungimento di questo è anche il motivo per cui entrambi xe ysono necessari.

  • La prima sostituzione in un sottoprogramma di carattere /␤\//xyf\z/o /␤\//xyb\z/, fa sì che ␤/alla fine della sottostringa condivisa diventi xyfzo xybz, immediatamente dopo la \/o \\.
  • La sostituzione /\\\\x\y/ /sostituisce \\xycon uno spazio e la sostituzione non /\\\/x\y//sostituisce \/xycon nulla.
    • Si applicano quando il carattere di input precedente stampato era rispettivamente a \o /.
    • La sottostringa condivisa ora contiene il numero appropriato di spazi per la stampa di un \successivo, seguito da fzo bz.
  • La sostituzione / \fz/\\\/␤\//sostituisce ​ fzcon \/␤/, e /b\z/\\\\␤\//sostituisce bzcon \\␤/.
    • Si applicano quando il carattere di input corrente è /o \, rispettivamente.
    • Il primo mangia uno spazio extra per posizionarlo /correttamente.
      • Se manca questo spazio (ovvero input che viola la condizione del prefisso), le seguenti sostituzioni vengono interpretate erroneamente, stampando molta spazzatura e di solito colpendo a ///, che è un ciclo infinito.
    • Ognuno aggiunge il comando corretto per stampare il proprio carattere e ripristina l'originale ␤/alla fine della sottostringa condivisa.
  • Il sottoprogramma del personaggio ha ora raggiunto la sua copia della sottostringa condivisa, che è pronta per stampare la sua linea.

Dopo che è stato eseguito l'ultimo sottoprogramma di caratteri, ciò che resta del programma è /␤\//xy. Poiché si tratta di una sostituzione incompleta con finale mancante /, il programma lo salta e si ferma normalmente.


1
La lingua giusta per il lavoro! Lol
DJMcMayhem

6

Gelatina , 14 byte

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

Un programma completo che stampa il risultato.

Provalo online!

Come?

=”\ðḤ’+\_⁸⁶ẋż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 byte

7 byte salvati grazie a Justin Mariner
+4 byte da correggere /\\/\\/(notato da Neil )

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

Provalo online!


5

MATL , 23 19 18 byte

1 byte spento grazie a @Sanchises

fGqoEq1yd~h*YsGZ?c

L'input è una stringa racchiusa tra virgolette singole.

Provalo online! Oppure verifica i casi di test: 1 , 2 , 3 .

Spiegazione

Considera l'input '\\\//\/\\'come esempio.

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: ['\  ';
                 ' \ ';
                 '  \';
                 '  /';
                 ' / ';
                 ' \ ';
                 ' / ';
                 ' \ ';
                 '  \']

A un byte da un algoritmo leggermente diverso per ottenere i tuoi indici: provalo online!
Sanchises,

@Sanchising Grazie per le modifiche molto appropriate!
Luis Mendo,

5

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

-1 byte grazie a Kevin Cruijssen

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

Emette una raccolta di stringhe, una per ogni riga. Il conteggio dei byte include anche:

using System.Linq;

Provalo online!

Spiegazione per la risposta di 77 byte:

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
Non funziona per /\\/\\/.
Neil,

@Neil grazie per averlo sottolineato! Fisso.
Grzegorz Puławski,

1
So che è passato un po 'di tempo, ma puoi salvare un byte cambiando s.Take(i).Sum(y=>y<92?-1:1)+(x-s[0])/45+1in(x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)
Kevin Cruijssen,

Nice one @KevinCruijssen!
Grzegorz Puławski,

4

05AB1E , 14 byte

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

Provalo online!

Spiegazione

Ç                # 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
Non funziona per /\\/\\/.
Neil,

Ç¥.¥0<.SηOv¹Nèy<ú, singhiozzando in binario
Magic Octopus Urn,

3

R , 122 121 byte

-1 byte grazie a 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="")

Provalo online!

Con spazi bianchi extra:

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="")
}

Spiegazione: Questa risposta si basa sull'osservazione che il numero di spazi iniziali cambia ogni riga di -1, più il numero di /nella riga precedente e corrente.

Se abbiamo N barre, la variabile yè un vettore di lunghezza N, con 1 per ogni posizione con \, 0 altrimenti. Pertanto, per ottenere la variazione del numero di spazi iniziali per riga, calcoliamo y[1:(N-1)] + y[2:N] - 1. La funzione diffinvconverte queste differenze in una sequenza, iniziando da 0. Il resto è solo una questione di assemblare ogni riga come il numero richiesto di spazi finali, seguito dalla barra corrispondente e da una nuova riga.


1
eh. Ho adottato un approccio alquanto diverso per 119 byte, il che mi fa chiedere se potremmo combinare i nostri approcci. (buon uso di diffinv;) Inoltre è possibile impostare y=x>")"per -1 byte
Giuseppe

@Giuseppe Dovresti postarlo come risposta separata, è un approccio abbastanza diverso. Il tuo è un bel modo di evitare di doverlo fare strsplit, che è sempre un assassino. Puoi anche utilizzare il famoso diffinv!
user2390246

1
Inoltre penso che se inserisci library(methods)l'intestazione (che dovrebbe essere OK senza penalità poiché quel pacchetto è parte base R), puoi usare el. Inoltre, diffinvsi è rivelato essere fino a quando cumsum! :)
Giuseppe,

Sì, lo stavo solo capendo, non funziona proprio in quel contesto
user2390246

bene, ho escogitato una soluzione alternativa , ma sì, questo *Srovina le cose.
Giuseppe,

3

Brain-Flak , 175 byte (174 caratteri + 1 bandiera)

Corri con la -cbandiera.

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

Provalo online!

Spiegazione

{ 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
{({}<>)(({})(())){({}[()]<([{}]())>)}{}{<>{}<>(<{}>)}{}<>}<>

Valuto sempre il cervello-flak. : D
DJMcMayhem

3

Rubino , 80 76 byte

-4 byte grazie a manatwork

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

Provalo online!

Spiegazione:

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
Quale versione di Ruby? La 2.3.3 ho richiede parentesi intorno parametro quando blocco di codice seguente: .each_cons(2){…}. In cambio puoi salvare sostituendo .each_char.chars.
arte

@manatwork La mia versione ruby ​​è 2.4.1. Grazie per il suggerimento sui caratteri, non lo sapevo.
Pazzaz,

È possibile salvare altri due byte spostandosi i+=all'inizio dell'espressione ternaria nidificata e terminandola con -1:1:0.
benj2240,

3

Java 8, 121 118 110 109 102 byte

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 byte grazie alla magia bit-saggia di @Nevay . :)

Spiegazione:

Provalo qui.

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 byte: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 Grazie. Sapevo che poteva essere abbreviato con alcune operazioni bit per bit, ma non riuscivo a capirlo. Soprattutto perché mi ero dimenticato di provare gli effetti di >>/ >>>/ <<... avevo verificato solo alcune cose con &/ |/ ~/ ^..>.>
Kevin Cruijssen

3

C (GCC), 137 134 97 byte

Provalo online!

• 3 byte grazie ATaco

• 37 byte grazie a Digital Trauma e 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);}}

Niente di speciale, solo una semplice funzione ricorsiva che prende una stringa e stampa le barre, si noti che l'input deve prima sfuggire alle barre rovesciate.

uso

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

Ungolfed

Questo è per la vecchia risposta, visualizza il link provalo online per quello aggiornato!

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);
}

Produzione

inserisci qui la descrizione dell'immagine


È possibile sostituire c=='\0'con !cper lo stesso effetto.
ATaco,

Fantastico grazie appena aggiornata la soluzione!
Addormentato

Puoi usare printf("%*s%c", n, "", c)per stampare il carattere con n spazi iniziali?
Trauma digitale

Sono abbastanza sicuro che è possibile risparmiare pochi byte sostituendo (c!=n)con c-ne riorganizzare espressioni ternari. Lo stesso con (c=='/'). Inoltre, è possibile sostituire '/'con un numero letterale 47. Penso che sia 7 byte in totale.



3

Retina , 47 byte

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

Provalo online! Il link include casi di test. Spiegazione:

^|\\
 $&

Aggiungi uno spazio all'inizio di ogni riga e prima di ciascuna \.

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

Considera i primi due caratteri della stringa. Se il primo è a, /il rientro deve essere ridotto; ciò si ottiene includendo lo spazio precedente nella cattura (che esiste sempre perché il primo stadio l'ha aggiunto); se il secondo è a \\allora deve essere incrementato; ciò si ottiene includendo lo spazio che il primo stadio ha aggiunto nella cattura. Dopo aver assegnato al secondo carattere il rientro corretto, lo stage viene ripetuto per il secondo e il terzo personaggio, ecc.

m`^ 

Rimuovi il rientro aggiuntivo.

Ho scritto una versione da 94 byte che (come la mia risposta Charcoal) consente qualsiasi combinazione di barre: provala online! Spiegazione:

.$
¶$.`$* $&

Fai rotolare la palla prendendo l'ultima barra e rientrando nella stessa posizione sulla sua stessa linea.

/
 /

Prefisso gli spazi a tutte le barre in avanti in modo che possano essere catturate.

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

Ripetere ripetutamente l'ultima barra dell'input e allinearla sulla propria riga con la barra sulla riga sottostante.

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

Elimina qualsiasi rientro residuo.

G`.

Elimina l'input ora vuoto.


2

Lua , 96 byte

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

Provalo online!

Quello più corto che potrei inventare a Lua. L'input viene preso dalla riga di comando.

Questo utilizza alcuni trucchi:

  1. (...):gmatch(
    Questa dovrebbe essere la forma più breve per ottenere una singola stringa in un programma Lua dalla riga di comando. L' ...espressione in Lua acquisisce tutti i parametri in eccesso su una funzione non specificata nella dichiarazione della funzione e viene utilizzata per varargs. Poiché il corpo principale di un programma Lua viene chiamato come una funzione con gli argomenti della riga di comando come parametri, gli argomenti della riga di comando finiranno in ....
    Le parentesi attorno ad essa trasformano l' ...espressione potenzialmente multi-valore in un'espressione a singolo valore. Considera questo esempio (un po 'sorprendente):
    function multipleReturnValues()
        return "abc", "def"
    end
    print(  multipleReturnValues()  ) --This prints: abc    def
    print( (multipleReturnValues()) ) --This prints: abc
  2. Il parser Lua non ha bisogno di alcun terminatore di riga, né di spazi bianchi tra le istruzioni, purché i token delle due istruzioni possano essere chiaramente separati e c'è solo un'interpretazione del testo che è codice Lua valido.
  3. Abuso and/ orper la logica "if x then value1 else value2".
    L' andoperatore di Lua restituisce il suo primo argomento se è falso; in caso contrario, restituisce il suo secondo argomento. L' oroperatore restituisce il suo primo argomento se è veritiero; altrimenti, il secondo argomento.
  4. pnon necessita di inizializzazioni.
    p==sdeve sempre essere falso nella prima esecuzione del ciclo, indipendentemente dall'input. Non impostare palcun valore prima di entrare nel loop (lasciandolo nil) farà sì che ciò accada e salverà anche i byte.

Qualcuno può giocare a golf (a Lua)?


Sono stato in grado di salvare due byte usando gsub invece di usare gmatch. c=0(...):gsub(".",function(s)c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end)
QuertyKeyboard,

Beh, non è importante. Avresti potuto facilmente salvato due byte cambiando gmatch(".")per gmatch"."come avete fatto nella vostra prossima risposta.
Tastiera Querty

@QuertyKeyboard È strano ... In realtà ho usato gsub esattamente così nella prima versione di questo codice, ma invece sono passato a gmatch perché in qualche modo si è rivelato più breve. Non so cosa ho fatto diversamente, sfortunatamente il file viene sovrascritto.
Jonathan S.


2

R , 119 byte

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="")

Provalo online!

Ciò differisce in qualche modo dalla risposta dell'utente2390246 . Ognuno di essi scorre sulla stringa, stampando un certo numero di caratteri spaziali e quindi il /\carattere appropriato .

Tuttavia, ho evitato di dividere la stringa, optando invece di sostituire i caratteri con il loro valore di codifica UTF-8, che mi consente quindi di eseguire direttamente l'aritmetica sui numeri, il che mi ha fatto risparmiare solo pochi byte.


Stavo riflettendo ancora su questo, penso che ci sia un errore nel tuo algoritmo: TIO
user2390246

@ user2390246 L'ho risolto! Ho avuto alcune parentesi fuori posto, ma ora diffinvsicuramente non funzionerà qui.
Giuseppe,


2

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

Ho provato la versione C # più corta

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

come è stato affermato: "Ciò significa anche che ogni input inizierà con una barra rovesciata". O leggermente più lungo che risolve l'avvio "/"

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

Provalo online!


Benvenuti nel sito! :)
DJMcMayhem

2

Lua , 88 84 byte

Versione migliorata (-4 byte grazie a QuertyKeyboard)

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

Provalo online!

Versione originale (88 byte)

Un altro tentativo in Lua, questa volta con un approccio completamente diverso usando la manipolazione di stringhe anziché una contro variabile.

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

C'è una cosa interessante nel codice: (...):gmatch"."
utilizza alcune stranezze nel parser Lua. Quando Lua incontra un pezzo di codice nel modulo func "string", lo convertirà in func("string"). Questo è così che si può scrivere print "string"per stampare una stringa costante e funziona solo con una singola stringa letterale dopo la funzione. Qualsiasi altra cosa genererà un errore di sintassi. Tuttavia, questo zucchero sintattico funziona anche con chiamate di funzione nel mezzo di un'espressione e, ancora più sorprendente, funziona bene insieme al :metodo chiamato zucchero sintattico. Quindi alla fine, Lua interpreterà il codice in questo modo:

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

Se qualcuno può pensare a un modo per rimuovere una delle tre chiamate gsub, per favore dimmelo.


1
Sono stato deluso nello scoprire che il mio trucco gsub che ho commentato nella tua altra risposta non ha funzionato del tutto per questo. In realtà ha finito per aggiungere un byte. Tuttavia, non mi arrenderei così facilmente. Innanzitutto, ho provato a memorizzare gsub come variabile per abbreviare il codice. Con mia sorpresa, il mio codice era esattamente la stessa quantità di byte - 88. Tuttavia, mi sono reso conto che con gsub salvato, il mio trucco gsub ora poteva funzionare! Ecco il mio codice che si è rasato 4 byte:s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)
QuertyKeyboard

@QuertyKeyboard Sì, ho anche provato a memorizzare gsub in una variabile prima del ciclo e poi a usarlo invece di scrivere gsub tre volte, e sono rimasto sorpreso nel vederlo fare assolutamente alcuna differenza. Combinare i trucchi "gsub anziché loop" e "store gsub" è davvero bello, non ci ho pensato! Grazie! :)
Jonathan S.


1

Perl, 40 + 2 byte

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

Hai bisogno della -Fbandiera.


1

Perl, 34 38 + 1 byte

per gestire i due casi

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

da eseguire con l' -popzione

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

EDIT: il seguente commento non funziona quando il primo personaggio è /

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

tuttavia l'output verrà spostato di un carattere a destra se il primo carattere è \


1
Non funziona per /\\/\\/.
Neil,

Con la domanda aggiornata la tua 34soluzione originale è ora perfettamente valida
Ton Hospel

1

VBA (Excel), 181 byte

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
Puoi golfare questo in modo significativo senza cambiare l'algoritmo sfruttando la natura di formattazione automatica di VBA di Excel e usando la [...]notazione: l'ho portato a 128 byte Sub 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

Grazie per aver giocato a golf la mia sceneggiatura. Ho imparato qualcosa da questo e applicherò in futuro. :) Non sapevo di poterlo utilizzare per recuperare i dati direttamente nelle celle. Grazie ancora :)
Ritocca il



Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.