Dibuja mis barras descendentes


60

Como programador, probablemente hayas oído hablar de barras inclinadas hacia adelante y hacia atrás. ¿Pero has oído hablar de las reducciones? Ahí es cuando tomas un montón de barras, conectas sus extremos y los dibujas bajando.

Para el desafío de hoy, debe escribir un programa o función que tome una cadena que consiste únicamente en barras, y genera todas esas barras dibujadas hacia abajo en una línea que las conecta. Esto será mucho más claro si ve un ejemplo. Dada la cadena \\\//\/\\, debe generar:

\
 \
  \
  /
 /
 \
 /
 \
  \

Aquí hay algunas aclaraciones:

  • Debe haber una barra oblicua por línea.

  • La primera línea tendrá 0 espacios iniciales.

  • Para cada par de barras:

    • Si son diferentes entre sí, se dibujarán en la misma columna. Por ejemplo, \/dará:

      \
      /
      
    • Si son del mismo carácter, el inferior está en la dirección apuntada , que se mueve hacia la derecha para una barra diagonal inversa y hacia la izquierda para una barra diagonal hacia adelante. Entonces \\//dará

      \
       \
       /
      /
      
  • Cada línea puede tener espacios en blanco finales adicionales siempre que esto no cambie la apariencia visual de la salida. Hasta una nueva línea final y líder también es aceptable. ¡ No se permiten espacios iniciales adicionales !

Para mantener esto más simple, puede suponer que la cadena nunca contendrá demasiadas barras diagonales. En otras palabras, ningún prefijo de la entrada contendrá más barras inclinadas que barras invertidas, por lo que una entrada como \\////o //nunca se dará. Esto también significa que cada entrada comenzará con una barra invertida.

Si su entrada se toma como un literal de cadena, puede escapar de las barras diagonales inversas si es necesario. Tampoco necesitará manejar una entrada que esté vacía o que contenga caracteres distintos de una barra diagonal.

Puede enviar por cualquier formato razonable .

Como de costumbre, este es un desafío de , así que trate de hacer la solución más corta posible, incluso si elige un idioma donde esto es bastante difícil. ¡Puntos de bonificación por explicar cualquier técnica interesante que utilizó para quitar bytes!

Ejemplos

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

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

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

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


#Input
\/\/\/

#Output
\
/
\
/
\
/

99
Las barras invertidas hacen una cantidad molesta de escape lol ...
totalmente humano

Respuestas:


20

GNU Sed, 20

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

Tenga en cuenta que ^Ly ^Hson caracteres literales de retroalimentación y retroceso (0x12 y 0x8).

Esta respuesta funciona moviendo el cursor usando los caracteres de retroceso y avance de página. Las barras diagonales / barras diagonales inversas no se rellenan con espacios a la izquierda. No estoy seguro de que esto descalifique esta respuesta. Esto no funciona en TIO, pero se ve bien en terminales comunes como xtermy gnome-terminal.

Recree este script sed de la siguiente manera:

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

Ejecútelo de la siguiente manera:

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

$ 

Explicación:

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

Carbón , 13 12 11 bytes

FS¿⁼ι/↓¶/↘ι

Pruébalo en línea! El enlace es a la versión detallada del código. Soporta //s adicionales . Explicación:

 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

Creo que ↓¶= "Mover a la izquierda" en la descripción no está bien.
Jonathan Allan

@JonathanAllan Eso es correcto (nueva línea impresa hacia abajo = moverse hacia la izquierda), aunque probablemente sería más claro decir "imprimir \n/hacia abajo"
solo ASCII

No lo dije print \n/ downporque sentí que era más útil describir el efecto del código en lugar de su traducción literal.
Neil

1
(Lengua en la mejilla: Describiendo el efecto = MyCode - Do the spec). Ahora lo entiendo, aunque el efecto es moverse hacia la izquierda; podría valer la pena decir "Mover a la izquierda (imprimiendo una nueva línea con una dirección de impresión hacia abajo)".
Jonathan Allan

¡El más conciso y autoexplicativo de todos!
j4hangir


10

/// , 119 bytes

/// no tiene comandos de entrada, por lo que la entrada debe estar incrustada en el programa. Para este, la cadena de entrada simplemente se agrega, sin necesidad de escapar.

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

Cómo funciona

  • A continuación, \\/\//se agregará una entrada de al programa para demostración.
  • se usa para representar nuevas líneas en el código en línea.

Abreviaturas

El comienzo /=/\/\///M/␤|%%=N/%|||=C/BA=del programa contiene sustituciones para abreviaturas de golf.

  • =se expande a //, Ma ␤|%%, Na %|||y Ca BA.
  • Después de esto, el programa actual se convierte en

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

Entrada de recodificación

La siguiente etapa transforma la cadena de entrada agregada en una forma más utilizable. Dado que consta completamente de los dos caracteres de comando de ///, esto tiene mucho cuidado para evitar destrozar el programa base.

  • La primera sustitución sustancial /\/\\/\/BA\\/, reemplaza la cadena /\con /BA\.
    • El programa base no contiene /\en este momento, por lo que esta sustitución no lo afecta.
    • Sin embargo, esto divide la cadena de entrada agregada en secuencias de \s seguidas de secuencias de /s, que junto con ABAel final del programa base permite iterar a través de él con las siguientes sustituciones.
    • Incluyendo el ABAprefijo antes, la cadena de entrada de ejemplo ahora se convierte en ABA\\/BA\//.
  • La siguiente sustitución /BA\\/BAbBA/, reemplaza BA\por BAbBA.
    • Debido a que /// las sustituciones se repiten hasta que ya no coinciden, esto itera a través de todos los \s de la cadena de entrada, que ahora con prefijo se convierteABAbBAbBA/BAbBA//
  • Del mismo modo, /B\A\//BAfBA/cambia BA/a BAfBA, iterando a través del /s.
    • El escape \en esta sustitución es necesario ya que de lo contrario sería destrozado por el anterior.
    • La entrada ahora se ha convertido en ABAbBAbBAfBABAbBAfBAfBA.
  • A continuación, /AB//elimina algunas partes superfluas de la codificación, convirtiéndola en AbBAbBAfBAbBAfBAfBA.
    • Esto también elimina una ABde la /|/AB\\/sustitución adelante en el programa, lo que se necesitaba para protegerlo de lo anterior /\manipulación.
    • En este punto, todas \las cadenas de entrada originales se han convertido AbB, y todas se /han convertido AfB. ( by fespera hacia atrás y hacia adelante). Hay un callejón Aal final.
  • Las siguientes dos sustituciones reemplazan todos los Asys Bcon fragmentos de programa para ejecutar en la etapa final. En las cadenas de reemplazo, %s y |s codificar lo que se convertirá en /s y \s respectivamente. Esto tiene dos beneficios:
    • A diferencia de /y \, los %sys |no necesitan escapar para ser copiados.
    • Las cadenas de reemplazo evitan contener la subcadena /\, que de lo contrario habría sido destrozada por las manipulaciones anteriores.
  • Después de esto, la sustitución /|/\\/(anteriormente /|/AB\\/) ahora decodifica la |s, después de lo cual se /%/|//ha convertido en lo siguiente /%/\//y decodifica la %s.

Estructura del programa en la etapa final.

En este punto, el programa base ha ejecutado todas sus sustituciones, y todo lo que queda es la codificación del programa de la cadena de entrada.

  • Cada carácter de entrada se ha convertido en un subprograma.

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

    (nueva línea final), donde *representa fpara un original /o bpara un original \.

  • También hay un comando de sustitución incompleto /␤\//xyal final del programa, que no tendrá ningún efecto, excepto para proporcionar una necesaria /para las sustituciones del subprograma anterior.

Subcadena compartida

Antes de que comience la iteración final a través de los subprogramas, hay una subcadena que cruza el límite después del subprograma de cada carácter del formulario \/␤/.

  • Estas subcadenas se utilizan como un estado global compartido. Todas las sustituciones restantes en el programa las manipularán de forma idéntica y en paralelo, de modo que al final del subprograma de cada carácter de entrada /se ejecutará su copia de esta subcadena compartida (excepto la final , que ancla las sustituciones) para imprimir la línea para ese personaje.
  • La versión inicial de la subcadena representa la impresión de una línea que contiene solo /, que es la "línea anterior" imaginaria correcta para que se imprima el primer carácter de entrada al comienzo de su línea.
  • En general, durante los pasos de impresión, la subcadena compartida consta de varios espacios, \\o \/, una nueva línea y un siguiente /.

Ejecutar un subprograma de caracteres

Varias de las siguientes sustituciones contienen \s adicionales en el interior para evitar que sean emparejados y mutilados entre sí (incluidas otras copias en otros subprogramas). El logro de esta es también la razón por la cual los dos xy yson necesarios.

  • La primera sustitución en un subprograma de caracteres, /␤\//xyf\z/o /␤\//xyb\z/, hace que ␤/al final de la subcadena compartida se convierta en xyfzo xybz, inmediatamente después de \/o \\.
  • La sustitución /\\\\x\y/ /reemplaza \\xypor un espacio, y la sustitución /\\\/x\y//reemplaza \/xypor nada.
    • Se aplican cuando el carácter de entrada anterior impreso era un \o /, respectivamente.
    • La subcadena compartida ahora contiene el número apropiado de espacios para imprimir un \siguiente, seguido de fzo bz.
  • La sustitución / \fz/\\\/␤\//reemplaza ​ fzpor \/␤/, y /b\z/\\\\␤\//reemplaza bzpor \\␤/.
    • Se aplican cuando el carácter de entrada actual es /o \, respectivamente.
    • El primero se come un espacio extra para colocar /correctamente.
      • Si falta este espacio (es decir, la entrada viola la condición del prefijo), las siguientes sustituciones se malinterpretan, imprimen una gran cantidad de basura y generalmente golpean a ///, que es un bucle infinito.
    • Cada uno agrega el comando correcto para imprimir su propio carácter y restablece el original ␤/al final de la subcadena compartida.
  • El subprograma de caracteres ha alcanzado su copia de la subcadena compartida, que está lista para imprimir su línea.

Después de que se haya ejecutado el último subprograma de caracteres, lo que queda del programa es /␤\//xy. Como se trata de una sustitución incompleta con un final faltante /, el programa lo omite y se detiene normalmente.


1
¡El lenguaje correcto para el trabajo! Lol
DJMcMayhem

6

Jalea , 14 bytes

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

Un programa completo que imprime el resultado.

Pruébalo en línea!

¿Cómo?

=”\ðḤ’+\_⁸⁶ẋż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 guardados gracias a Justin Mariner
+4 bytes para arreglar /\\/\\/(notado por Neil )

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

Pruébalo en línea!


5

MATL , 23 19 18 bytes

1 byte de descuento gracias a @Sanchises

fGqoEq1yd~h*YsGZ?c

La entrada es una cadena entre comillas simples.

Pruébalo en línea! O verificar los casos de prueba: 1 , 2 , 3 .

Explicación

Considere la entrada '\\\//\/\\'como un ejemplo.

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

Un byte desactivado por un algoritmo ligeramente diferente para obtener sus índices: ¡ Pruébelo en línea!
Sanchises

@Sanchises ¡Gracias por tus ediciones muy apropiadas!
Luis Mendo

5

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

-1 byte gracias a Kevin Cruijssen

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

Emite una colección de cadenas, una para cada línea. El recuento de bytes también incluye:

using System.Linq;

Pruébalo en línea!

Explicación de la respuesta de 77 bytes:

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
No funciona para /\\/\\/.
Neil

@Neil gracias por señalar eso! Fijo.
Grzegorz Puławski

1
Sé que ha pasado un tiempo, pero puedes guardar un byte cambiando s.Take(i).Sum(y=>y<92?-1:1)+(x-s[0])/45+1a(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ú»

Pruébalo en línea!

Explicación

Ç                # 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
No funciona para /\\/\\/.
Neil

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

3

R , 122 121 bytes

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

Pruébalo en línea!

Con espacios en blanco adicionales:

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

Explicación: Esta respuesta se basa en la observación de que el número de espacios iniciales cambia cada línea en -1, más el número de /líneas anteriores y actuales.

Si tenemos N barras diagonales, la variable yes un vector de longitud N, con 1 para cada posición con \, 0 de lo contrario. Por lo tanto, para obtener el cambio en el número de espacios iniciales por línea, calculamos y[1:(N-1)] + y[2:N] - 1. La función diffinvconvierte estas diferencias en una secuencia, comenzando con 0. El resto es solo una cuestión de ensamblar cada línea como el número requerido de espacios finales, seguido de la barra oblicua relevante y una nueva línea.


1
eh Tomé un enfoque bastante diferente para 119 bytes, lo que me hace preguntarme si podríamos combinar nuestros enfoques. (buen uso de diffinv;) También puede configurar y=x>")"para -1 byte
Giuseppe

@Giuseppe Deberías publicar eso como una respuesta separada, es un enfoque lo suficientemente diferente. La tuya es una buena manera de evitar tener que hacerlo strsplit, lo que siempre es un asesino. ¡También puedes hacer uso de los famosos diffinv!
user2390246

1
También creo que si pones library(methods)en el encabezado (que debería estar bien sin penalización ya que ese paquete es parte base R), puedes usarlo el. Además, diffinvresultó ser tan largo como cumsum! :)
Giuseppe

Sí, me estaba dando cuenta de que también, no funciona en ese contexto
User2390246

bueno, se me ocurrió una solución , pero sí, eso *Sarruina las cosas.
Giuseppe

3

Brain-Flak , 175 bytes (174 caracteres + 1 bandera)

Corre con -cbandera.

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

Pruébalo en línea!

Explicación

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

Siempre voté por el ataque cerebral. : D
DJMcMayhem

3

Ruby , 80 76 bytes

-4 bytes gracias a manatwork

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

Pruébalo en línea!

Explicación:

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
¿Qué versión de Ruby? La 2.3.3 Tengo exige paréntesis alrededor de parámetro al bloque de código siguiente: .each_cons(2){…}. En cambio, puede guardar reemplazando .each_char.chars.
manatwork

@manatwork Mi versión ruby ​​es 2.4.1. Gracias por la sugerencia sobre los caracteres, no sabía sobre eso.
Pazzaz

Puede guardar otros dos bytes moviéndose i+=al comienzo de la expresión ternaria anidada y finalizándola con -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 gracias a la magia sabia de @Nevay . :)

Explicación:

Pruébalo aquí

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 Gracias. Sabía que podría acortarse con algunas operaciones bit a bit, pero no pude resolverlo. Principalmente porque olvidé probar los efectos de >>/ >>>/ <<... Solo había verificado algunas cosas con &/ |/ ~/ ^..>.>
Kevin Cruijssen

3

C (GCC), 137 134 97 bytes

Pruébalo en línea!

• 3 bytes gracias ATaco

• 37 bytes gracias a Digital Trauma y 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);}}

Nada demasiado elegante, solo una función recursiva simple que toma una cadena e imprime las barras diagonales, tenga en cuenta que la entrada debe escapar primero de las barras diagonales inversas.

Uso

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

Sin golf

Esto es para la respuesta anterior, ¡mira el enlace para probarlo en línea para obtener una actualizada!

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

Salida

ingrese la descripción de la imagen aquí


Puede reemplazar c=='\0'con !cel mismo efecto.
ATaco

¡Impresionante, gracias por actualizar la solución!
Asleepace

¿Se puede utilizar printf("%*s%c", n, "", c)para imprimir el carácter con n espacios iniciales?
Trauma digital

Estoy bastante seguro de que puede ahorrar unos pocos bytes mediante la sustitución (c!=n)con c-ny reordenando las expresiones ternarias. Lo mismo con (c=='/'). Además, puede reemplazar '/'con un número literal 47. Creo que son 7 bytes en total.



3

Retina , 47 bytes

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

Pruébalo en línea! El enlace incluye casos de prueba. Explicación:

^|\\
 $&

Agregue un espacio al comienzo de cada línea y antes de cada una \.

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

Considere los dos primeros caracteres de la cadena. Si el primero es un, /entonces la sangría necesita ser decrementada; esto se logra al incluir el espacio anterior en la captura (que siempre existe porque la primera etapa lo agregó); si el segundo es a, \\entonces necesita ser incrementado; esto se logra al incluir el espacio que la primera etapa agregó en la captura. Habiendo dado al segundo carácter la sangría correcta, la etapa se repite para el segundo y tercer carácter, etc.

m`^ 

Eliminar la sangría adicional.

He escrito una versión de 94 bytes que (como mi respuesta de carbón) permite cualquier combinación de barras: ¡ Pruébelo en línea! Explicación:

.$
¶$.`$* $&

Haga rodar la pelota tomando el último corte y sangrando en la misma posición en su propia línea.

/
 /

Prefije espacios en todas las barras inclinadas para que puedan capturarse.

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

Repetidamente tome la última barra diagonal de la entrada y alinéela en su propia línea con la barra diagonal en la línea de abajo.

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

Elimine cualquier sangría restante.

G`.

Eliminar la entrada ahora vacía.


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

Pruébalo en línea!

La más corta que se me ocurrió en Lua. La entrada se toma de la línea de comando.

Esto usa algunos trucos:

  1. (...):gmatch(
    Esta debería ser la forma más corta de obtener una sola cadena en un programa Lua desde la línea de comandos. La ...expresión en Lua captura cualquier exceso de parámetros en una función que no se especifica en la declaración de la función y se usa para varargs. Como el cuerpo principal de un programa Lua se llama como una función con los argumentos de la línea de comando como sus parámetros, los argumentos de la línea de comando terminarán en ....
    Los paréntesis a su alrededor convierten la ...expresión potencialmente multivalorizada en una expresión de valor único. Considere este ejemplo (algo sorprendente):
    function multipleReturnValues()
        return "abc", "def"
    end
    print(  multipleReturnValues()  ) --This prints: abc    def
    print( (multipleReturnValues()) ) --This prints: abc
  2. El analizador Lua no necesita ningún terminador de línea, ni siquiera espacios en blanco entre las declaraciones, siempre que los tokens de las dos declaraciones se puedan separar claramente y solo haya una interpretación del texto que sea código Lua válido.
  3. Abusar and/ orpara la lógica "if x then value1 else value2".
    El andoperador de Lua devuelve su primer argumento si es falso; de lo contrario, devuelve su segundo argumento. El oroperador devuelve su primer argumento si es verdadero; de lo contrario, el segundo argumento.
  4. pNo necesita ninguna inicialización.
    p==ssiempre tiene que ser falso en la primera ejecución del bucle, independientemente de la entrada. Si no establece pningún valor antes de ingresar al ciclo (dejarlo nil), eso sucederá y también se guardarán bytes.

¿Alguien puede jugar al golf esto (en Lua)?


Pude guardar dos bytes usando gsub en lugar de usar 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

Bueno, no es que importe. Podría haber guardado fácilmente dos bytes cambiando gmatch(".")a gmatch"."como lo hizo en su próxima respuesta.
QuertyKeyboard

@QuertyKeyboard Eso es extraño ... En realidad utilicé gsub exactamente así en la primera versión de este código, pero luego cambié a gmatch porque de alguna manera resultó más corto. Sin embargo, no sé qué hice diferente, desafortunadamente el archivo se sobrescribe.
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="")

Pruébalo en línea!

Esto difiere un poco de la respuesta del usuario 2390246 . Cada uno itera sobre la cadena, imprimiendo un cierto número de caracteres de espacio y luego el /\carácter apropiado .

Sin embargo, evité dividir la cadena, optando por reemplazar los caracteres con su valor de codificación UTF-8, lo que me permite hacer aritmética en los números directamente, lo que me ahorró solo unos pocos bytes.


Solo he estado reflexionando sobre esto un poco más, creo que hay un error en su algoritmo: TIO
user2390246

@ user2390246 ¡Lo arreglé! Tenía algunos paréntesis fuera de lugar, pero ahora diffinvdefinitivamente no funcionará aquí.
Giuseppe


2

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

Intenté una versión más corta de C #

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

como se dijo: "Esto también significa que cada entrada comenzará con una barra diagonal inversa". O un poco más de tiempo que resuelven el inicio "/"

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

Pruébalo en línea!


Bienvenido al sitio! :)
DJMcMayhem

2

Lua , 88 84 bytes

Versión mejorada (-4 bytes gracias a QuertyKeyboard)

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

Pruébalo en línea!

Versión original (88 bytes)

Otro intento en Lua, esta vez con un enfoque completamente diferente utilizando la manipulación de cadenas en lugar de una variable de contador.

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

Sin golf:

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

Hay una cosa interesante en el código: (...):gmatch"."
utiliza algunas peculiaridades en el analizador Lua. Cuando Lua encuentra un fragmento de código en el formulario func "string", lo convertirá a func("string"). Esto es para que uno pueda escribir print "string"para imprimir una cadena constante y solo funciona con un solo literal de cadena después de la función. Cualquier otra cosa dará un error de sintaxis. Sin embargo, este azúcar sintáctico también funciona con llamadas de función en el medio de una expresión y, lo que es más sorprendente, funciona bien junto con el :método llamado azúcar sintáctico. Entonces, al final, Lua interpretará el código así:

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

Si alguien puede pensar en una forma de eliminar una de las tres llamadas gsub, dígame.


1
Me decepcionó encontrar que mi truco gsub que comenté en su otra respuesta no funcionó para esta. En realidad terminó agregando un byte. Sin embargo, no me rendiría tan fácilmente. Primero, intenté almacenar gsub como una variable para acortar el código. Para mi sorpresa, mi código tenía exactamente la misma cantidad de bytes: 88. Sin embargo, me di cuenta de que al guardar gsub, ¡mi truco gsub ahora podía funcionar! Aquí está mi código que eliminó 4 bytes:s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)
QuertyKeyboard

@QuertyKeyboard Sí, también intenté almacenar gsub en una variable antes del ciclo y luego usarlo en lugar de escribir gsub tres veces, y me sorprendió ver que no hacía absolutamente ninguna diferencia. Combinar los trucos "gsub en lugar de loop" y "store gsub" es realmente genial, ¡no pensé en eso! ¡Gracias! :)
Jonathan S.


1

Perl, 40 + 2 bytes

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

Necesitas la -Fbandera.


1

Perl, 34 38 + 1 bytes

para manejar los dos casos

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

para ejecutarse con -popción

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

EDITAR: el siguiente comentario no funciona cuando el primer personaje es /

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

sin embargo, la salida se desplazará un carácter a la derecha si el primer carácter es \


1
No funciona para /\\/\\/.
Neil

Con la pregunta actualizada, su 34solución original ahora es perfectamente válida
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
Puede reducir esto significativamente sin cambiar su algoritmo aprovechando la naturaleza de formato automático de Excel VBA y mediante el uso de [...]notación: lo reduje a 128 Bytes 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

Gracias por jugar golf mi guión. Aprendí algo de esto y lo aplicaré en el futuro. :) No sabía que puedo usar eso para obtener datos directamente en las celdas. Gracias de nuevo :)
remoel



Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.