Salida de una tienda al revés

27

Dado un número entero, genera una tienda al revés.

La entrada determina tanto el tamaño de la tienda (valor absoluto) como si la entrada está en el lado izquierdo (números negativos) o en el lado derecho (números positivos).

If input = -1:
____
\/_/

If input = -2:
________
\  /   /
 \/___/

If input = -3:
____________
\    /     /
 \  /     /
  \/_____/

If input = 1:
____
\_\/

If input = 2:
________
\   \  /
 \___\/

If input = 3:
____________
\     \    /
 \     \  /
  \_____\/

et cetera

Tenga en cuenta que la parte superior de la tienda (es decir, la última línea) tiene 2 * abs(input) - 1guiones bajos.

No puede haber ninguna espacios iniciales, de tal manera que la primera línea comienza directamente con un guión bajo.

Suponga que la entrada nunca será 0.

Su código debe ser lo más corto posible.

Este desafío se basa en un mini desafío de chat de Helka Homba , que puede usarse en desafíos reales bajo las condiciones de la Licencia pública de pasatiempos de Calvin .

usuario48538
fuente
1
¿Están bien los espacios finales? Es decir, ¿podemos generar cuatro cadenas de 12 longitudes (un rectángulo) como entrada, 3por ejemplo?
AdmBorkBork
1
@TimmyD Ellos están permitidos.
user48538
2
@TimmyD seguro, ese es probablemente un engañado de otra cosa también, no estoy realmente seguro de dónde comienza la cadena. Creo que ya hemos visto suficientes de estos.
Nathaniel
55
No veo cómo las preguntas son remotamente similares. Claro, ambos son desafíos ascii-art que toman un número y hacen que salga la enésima iteración de algo, pero ahí es donde termina la similitud. Si eso es suficiente para cerrar como engañado, no deberíamos tomar más desafíos de ascii-art en absoluto.
DJMcMayhem
2
@Nathaniel Nuestra pauta aceptada para que dos desafíos sean duplicados es si las respuestas de una pueden reutilizarse (competitivamente) en la otra con poca o ninguna modificación. Si los desafíos aportan algo nuevo a la mesa no es parte de esa directriz. Utilice los votos negativos para los desafíos que desea desalentar o simplemente ignórelos si no creen que sean interesantes y deje que quienes los disfruten.
Martin Ender

Respuestas:

11

MATL , 55 53 52 51 bytes

|95cy4*Y"DXytPEt0*yvG0>?P_]!'\/ 'w)95JG|G0<yEq:++&(

Pruébalo en línea!

Explicación

Deje Ndenotar la entrada. El código procede en tres pasos.

Primero , la primera línea de 4*Nguiones bajos se construye como una cadena y se muestra (lo que la elimina de la pila).

Segundo , el "marco" de la tienda se construye usando los dos tipos de barras. Para hacer esto, se crea una matriz numérica 2D que contiene 1y 2corresponde a los dos tipos de barras, y 0para el espacio.

Esto se hace concatenando cuatro matrices:

  1. Una matriz de identidad de tamaño abs (N);
  2. Una matriz del mismo tamaño que contiene 2en el antidiagonal;
  3. Una matriz nula del mismo tamaño;
  4. Una copia de la matriz 2.

Concatenando estas cuatro matrices verticalmente da, usando N=3como ejemplo, la siguiente 4*N × Nmatriz:

1 0 0
0 1 0
0 0 1
0 0 2
0 2 0
2 0 0
0 0 0
0 0 0
0 0 0
0 0 2
0 2 0
2 0 0

(que, transpuesta, comienza a parecerse a la tienda).

Ahora nos encargamos del signo de la entrada. Si es positivo, simplemente transponemos la matriz y el índice anteriores en la cadena '\/ '. La indexación se basa en 1 y es modular, por lo que se 1convierte '\', se 2convierte '/'y se 0convierte ' ', produciendo la matriz de caracteres 2D

\    /     /
 \  /     / 
  \/     /  

Por otro lado, si la entrada es negativa, volteamos verticalmente y negamos aritméticamente la 4*N × Nmatriz, produciendo

-2  0  0
 0 -2  0
 0  0 -2
 0  0  0
 0  0  0
 0  0  0
-2  0  0
 0 -2  0
 0  0 -2
 0  0 -1
 0 -1  0
-1  0  0

El índice -1ahora se refiere a '/'y -2a '\'. Es decir, los dos tipos de barras han sido intercambiados, según sea necesario. Una vez más, la transposición y la indexación en la cadena '\/ 'da la carpa invertida:

\     \    /
 \     \  / 
  \     \/  

Tercero , los guiones bajos deben completarse en parte de la última fila de la matriz de caracteres 2D. La posición horizontal de esta línea depende del signo de la entrada, y su longitud es abs(N).

Una vez que los espacios correspondientes han sido reemplazados por guiones bajos, el resultado se muestra implícitamente, debajo de la línea inicial de guiones bajos que ya se mostró en el primer paso.

Luis Mendo
fuente
¿No deberían esos subrayados al principio ser espacios?
DJMcMayhem
@DJMcMayhem Lo siento, ¿qué quieres decir?
Luis Mendo
Cuando ejecuto su código, la primera línea es todos los guiones bajos. La salida que dio zyabin no tiene eso.
DJMcMayhem
@DJMcMayhem No sigo. La primera línea en los casos de prueba son los guiones bajos, ¿no? ¿Y otras respuestas (no la suya) también lo hacen?
Luis Mendo
1
@DJMcMayhem :-D Ciertamente extraño. ¿Prueba un navegador diferente?
Luis Mendo
9

Javascript (ES6), 139 bytes

Construye la carpa recursivamente:

f=(N,n=N>0?N:-N,i=0,r=(j,i)=>' _'[i||0].repeat(j),a=`\\${r(i)}/`,b=r(n*2+i-1,+!i))=>n--?f(N,n,i+2)+`
`+r(n)+(N<0?a+b+'/':'\\'+b+a):r(i*2,1)

Ungolfed y comentó

f = (
  N,                                  // N is the original parameter (remains unchanged)
  n = N > 0 ? N : -N,                 // n is initialized to abs(N)
  i = 0,                              // i is the row counter (*2)
  r = (j, i) => ' _'[i||0].repeat(j), // helper function to repeat ' ' or '_' j times
  a = `\\${r(i)}/`,                   // a = '\ /' pattern
  b = r(n*2+i-1, +!i)                 // b = padding pattern filled with ' ' or '_'
) =>
  n-- ?                               // if we haven't made it yet to the top row:
    f(N, n, i+2) + `\n` +             //   - compute next row(s) / append line break
    r(n) +                            //   - append leading spaces
    (N < 0 ? a+b+'/' : '\\'+b+a)      //   - append a/b patterns according to N sign
  :                                   // else:
    r(i*2, 1)                         //   - return top row, made of '_' characters

Ejemplos

var f=(N,n=N>0?N:-N,i=0,r=(j,i)=>' _'[i||0].repeat(j),a=`\\${r(i)}/`,b=r(n*2+i-1,+!i))=>n--?f(N,n,i+2)+`
`+r(n)+(N<0?a+b+'/':'\\'+b+a):r(i*2,1)

console.log(f(3));
console.log(f(-4));

Arnauld
fuente
6

Python 2, 143 141 139 138 137 bytes

-2 bytes gracias a @ Sp3000 (no es necesario paréntesis exec en Python 2)
-1 byte gracias a @ Sp3000 (uso cmp)

def f(n):d=cmp(n,0);a,b='\/'[::-d];s=n*d;x=2*s-1;y=4*s;print'_'*y;i=0;exec"print' '*i+(b+' '*(y-3-x-i-i)+a+'_ '[s-i>1]*x+a)[::d];i+=1;"*s

Pruébalo en ideone

Primero vemos si nes negativo y hacemos d +1si es y -1si no.
Luego seleccionamos las dos barras inclinadas, ay b, usando dtal que a='\', b='/'cuando nsea ​​positivo y a='/', b='\'cuando nsea ​​negativo.
A continuación establecemos lo s=abs(n)que puede lograrse mediante s=n*d.
Luego calculamos el número _en la parte superior (parte inferior de la imagen), que también es el número en el costado de la tienda como x=2*s-1.
Luego calculamos el número _en la base de la tienda (parte superior de la imagen), y lo almacenamos como y=4*sse usará en el bucle para crear el resto de la tienda.
Ahora imprimimos la base de la tienda usando print'_'*y.
Luego imprimimos el resto de la tienda ejecutando sdeclaraciones de impresión con una variable de bucle iinicializada a la 0que se incrementa 1para cada declaración de impresión.
El resto de la carpa tiene y-3-x-i-iespacios en la puerta y xespacios en el cuerpo hasta que se alcanza la parte superior, cuando se s-i>1evalúa como Falso, eligiendo el _de '_ '.
Para una carpa positiva de puerta izquierda, toda la carpa, excluyendo los espacios iniciales, es de atrás hacia adelante, por lo que se invierte mientras que la carpa positiva de `` puerta derecha '' no está [::d].

Jonathan Allan
fuente
@ Sp3000 desafortunadamente cmp(0,0)regresa0
Jonathan Allan
5

Python 2, 121 bytes

def f(n):i=k=abs(n);print'_'*k*4;exec"print' '*(k-i)+r'\\\%%s%\*%c%%*sc/'[n<0::2]%(' _'[i<2]*(2*k-1))%(2*i-1,47);i-=1;"*k

Solo mucho formato de cadena.

Sp3000
fuente
5

C #, 215 214 bytes

string t(int N){var n=N<0;N=n?-N:N;var t=new string('_',4*N);for(int i=0;i<N;){string f=new string(i<N-1?' ':'_',2*N-1),p=new string(' ',2*N-2*i-2);t+='\n'+new string(' ',i++)+'\\'+(n?p+'/'+f:f+'\\'+p)+'/';}return t;}

Existe la posibilidad de guardar algunos bytes cuando se usa de using s=string;antemano.

s t(int N){var n=N<0;N=n?-N:N;var t=new s('_',4*N);for(int i=0;i<N;){s f=new s(i<N-1?' ':'_',2*N-1),p=new s(' ',2*N-2*i-2);t+='\n'+new s(' ',i++)+'\\'+(n?p+'/'+f:f+'\\'+p)+'/';}return t;}

que sería 15 (usando) + 184 (método) = 199 bytes.

BackFromExile
fuente
55
¡Bienvenido a PPCG, BackFromExile!
Erik the Outgolfer
De hecho, ¡bienvenido a PPCG! Una muy buena primera respuesta +1. Traté de encontrar algo para el golf (bastante tiempo desde que programé en C #), y al final solo pude encontrar una cosa para -1 byte: si cambia el primero vardentro del ciclo for string, puede eliminar el segundo var (incluyendo espacio para guardar el byte). Entonces se var fvuelve string fy se ;var p=vuelve ,p=.
Kevin Cruijssen
4

TSQL, 195 bytes

Golfizado:

DECLARE @ INT=-2
DECLARE @b INT=ABS(@),@i INT=0PRINT REPLICATE('_',4*@b)z:SET @i+=1PRINT SPACE(@i-1)+'\'+STUFF(REPLICATE(IIF(@i<@b,' ','_'),4*@b-2*@i),@b*2-IIF(@<0,@i*2-1,0),1,IIF(@<0,'/','\'))+'/'IF @i<@b GOTO z

Sin golf:

DECLARE @ INT=-2

DECLARE @b INT=ABS(@),@i INT=0

PRINT REPLICATE('_',4*@b)
z:
  SET @i+=1
  PRINT 
    SPACE(@i-1)+'\'
    +STUFF(REPLICATE(IIF(@i<@b,' ','_'),
      4*@b-2*@i),@b*2-IIF(@<0,@i*2-1,0),1,IIF(@<0,'/','\'))
    +'/'
IF @i<@b GOTO z

Violín

t-clausen.dk
fuente
4

V , 66 bytes

é /ä
"aDoÀñá_>ñ^hr\A\/ò^hÄX$2é_Ó_/ òÄÒ_ñ/-
ddÍܨ[ _]*©Ü¨ *©/ܲ¯±

Pruébalo en línea!

Este es un enfoque bastante ingenuo, así que intentaré jugarlo más tarde hoy. Esta solución contiene caracteres no imprimibles, así que aquí hay un hexdump:

0000000: e920 2fe4 0a22 6144 6f1b c0f1 e15f 3ef1  . /.."aDo...._>.
0000010: 5e68 725c 415c 2f1b f25e 68c4 5824 32e9  ^hr\A\/..^h.X$2.
0000020: 5fd3 5f2f 20f2 c4d2 5ff1 2f2d 0a64 64cd  _._/ ..._./-.dd.
0000030: dca8 5b20 5f5d 2aa9 dca8 202a a92f dcb2  ..[ _]*... *./..
0000040: afb1                                     ..
DJMcMayhem
fuente
4

05AB1E , 52 bytes

Ä©'_4®*×,FNð×'\®·<N>®Qi'_ëð}×®N>-·ð×®¹Qi'\ës'/}s'/J,

Explicación

                                                     # implicit input, call this A
Ä©                                                   # store abs(A) in register for later use
  '_4®*×,                                            # print 4*A underscores (tent floor)
         F                                           # for each non-floor section in range(N)
          Nð×'\                                      # push N spaces at the beginning of the 
                                                     # row followed by a backslash
                  N>®Qi'_ëð}                         # if we're on the last row push an
                                                     # underscore, else a space
               ®·<          ×                        # repeat that char abs(A)*2-1 times
                             ®N>-·ð×                 # push 2*(abs(A)-(N+1)) spaces
                                    ®¹Qi'\ës'/}      # if input is positive push backslash
                                                     # else push a slash
                                               s'/   # move that char between the 2 sections
                                                     # of spaces
                                                  J, # join the row and print

Pruébalo en línea!

Emigna
fuente
4

PowerShell v2 +, 217 205 190 187 184 bytes

param($b)"_"*(($a=[math]::Abs($b))*4);$z,$y='/\'[($b=$b-lt0),!$b]
((($x=1..$a|%{($w=" "*($_-1))+$z+" "*(2*($a-$_))+$y+(' ','_')[$_-eq$a]*($a*2-1)+$y+$w})|%{-join$_[($a*4)..0]}),$x)[$b]

Toma la entrada $bcomo un entero. Tenga en cuenta que si $bes negativo, debe rodearlo explícitamente con parens para emitirlo adecuadamente (ver ejemplos), de lo contrario, PowerShell pensará que es una cadena.

Independientemente de en qué dirección esté mirando la carpa, la primera línea es la misma, un montón de guiones bajos; exactamente 4*abs(input)muchos de ellos, en realidad. Ese número también se almacena $apara su uso posterior. Además, ahora que tenemos el valor absoluto de $balmacenado en $a, nos convertimos $ben un booleano para su signo y elegimos nuestras barras almacenadas en $yy $z.

La siguiente línea es la construcción y formulación de la salida, y es un doozy, así que vamos a desglosarlo.

Básicamente, estamos indexando en una matriz de dos elementos, (big long calculations saved into $x)o $x, en base a $b.

Los cálculos son donde se construye el cuerpo de la tienda. Hacemos un bucle desde 1..$a|%{...}. Cada iteración estamos construyendo una línea del cuerpo de la tienda. Comenzamos con una cantidad de espacios igual a la línea # en la que estamos -1, para que esté alineada a la izquierda de manera apropiada. Eso se almacena $wpara más adelante, y se concatena con la barra inclinada apropiada ($ z, según $b), luego el número de espacios en el marco de la puerta, luego la otra barra inclinada $y, luego los guiones bajos o espacios dependiendo de si estamos en la línea de fondo o no, luego otra barra oblicua $y, y finalmente el número apropiado de espacios finales ( $w) para construir una cadena rectangular. Esa matriz resultante de cadenas se almacena en $x.

Si se selecciona la mitad izquierda de la matriz (es decir, $bes Falsedesde la entrada era positivo), entonces tenemos que bucle a través de $xy revertir cada elemento de línea - aquí es donde los espacios finales entran en juego; nos permite simplemente invertir las líneas en lugar de volver a calcular distancias.

Si $bes así True, se selecciona la mitad derecha de la matriz $x.

En cualquier caso, la tubería ahora contiene una serie de cadenas. La salida implícita a través de Write-Outputocurre al finalizar el programa, con una nueva línea predeterminada entre los elementos.

Ejemplos

PS C:\Tools\Scripts\golfing> .\print-upside-down-tent.ps1 (-5)
____________________
\        /         /
 \      /         / 
  \    /         /  
   \  /         /   
    \/_________/    

PS C:\Tools\Scripts\golfing> .\print-upside-down-tent.ps1 (4)
________________
\       \      /
 \       \    / 
  \       \  /  
   \_______\/   
AdmBorkBork
fuente
3

Haskell, 187 184 183 bytes

f x=unlines$[(n*4)%'_']++((' '#)<$>[0..n-2])++['_'#(n-1)]where m#i=i%' '++'\\':m!i++"/";m!i|x>0=(2*n-1)%m++'\\':(2*(n-i-1))%' '|q<-2*(n-i-1)=q%' '++'/':(2*n-1)%m;n=abs x;m%c=c<$[1..m]

Siento que este no es un gran puntaje para Haskell, por lo que cualquier idea de mejora es bienvenida.

  • 3 bytes guardados gracias a @Myridium
  • 1 byte guardado gracias a @nimi

Sin golf

tent :: Int -> String
tent x = unlines $ [replicate (n*4) '_'] ++ (row ' '<$>[0..n-2]) ++ [row '_' (n-1)]
    where row m i = replicate i ' ' ++ "\\" ++ dir m i ++ "/"
          -- direction selector
          dir m i | x > 0 = side m ++ "\\" ++ entrance i ' '
                  | 1 > 0 = entrance i ' ' ++ "/" ++ side m
          side = replicate (2*n-1)
          entrance i = replicate (2*(n-i-1))
          n = abs x
sudee
fuente
Mejor que mis 290 bytes que estaba a punto de publicar ...
Myridium
¿No debería agregar un mainpara que acepte stdincomo entrada?
Myridium
Puede publicar una sola función a menos que la pregunta especifique lo contrario. Hay un metahilo para las reglas generales de respuesta, intentaré encontrarlo por ti.
sudee
1
Puede guardar 2 bytes cambiando dónde antepone un solo carácter para usar el :carácter. es decir, cambiar "\\" ++ entrance...a '\\':entrance.
Myridium
1
No malgastes la guardia "de lo contrario" : puedes cambiar |1>0=(2*(n-i-1))%' 'a |q<-2*(n-i-1)=q%' '.
nimi
2

C, 240 207 193 Bytes

#define P putchar
a,j,l,m;g(x,y,z){for(m=y+z+1;m--;P(m^z?l?32:95:x));}f(n){g(32,(a=abs(n))*4,0);for(P(10),j=2*(l=a)-1;l--;){for(m=a;--m>l;P(32));P(92);m=n>0?g(92,j,l*2):g(47,l*2,j);puts("/");}}

Esta vez optimicé la función g (...) para usar un solo bucle for.

#define P putchar
a,j,l,m;g(x,y,z){for(;y--;P(l?32:95));for(P(x);z--;P(l?32:95));}f(n){g(32,(a=abs(n))*4,0);l=a;j=2*a-1;P(10);for(;l--;){for(m=a;--m>l;P(32));P(92);m=n>0?g(92,j,l*2):g(47,l*2,j);puts("/");}}

Esta vez, la macro X está mejor como una función g (...) y dado que y y z son parámetros en un nuevo alcance, puedo disminuirlos en el alcance de g.

#define P putchar
#define X(x,y,z){for(k=0;k++<y;P(l?32:95));P(x);for(k=0;k++<z;P(l?32:95));}
a,i,j,k,l,m;f(n){for(l=a=abs(n);i++<a*4;P(95));j=2*a-1;P(10);while(l--){for(m=a;--m>l;P(32));P(92);if(n>0)X(92,j,l*2)else X(47,l*2,j)puts("/");}}

Prueba con esta función principal; Esto debería ser mucho más pequeño.

main(c,v)char**v;
{
    f(atoi(v[1]));
}
cleblanc
fuente
2

C # 241 231 Bytes

Guardado 10 bytes gracias a @Kevin Cruijssen

using s=System.String;s f(int N){var f=N<0;N=N>0?N:-N;var o=new s('_',N*4);for(int j=0,z;j<N;){z=-2*j+2*N-2;var O=j>N-2?'_':' ';o+='\n'+new s(' ',j)+'\\'+new s(' ',z)+(f?'/':O)+new s(O,j++*2)+(f?O:'\\')+new s(' ',z)+'/';}return o;}

Versión antigua:

string f(int N){var f=N<0;N=N>0?N:-N;var o=new string('_',N*4);for(int j=0;j<N;){int z=-2*j+2*N-2;var O=j>N-2?'_':' ';o+='\n'+new string(' ',j)+'\\'+new string(' ',z)+(f?'/':O)+new string(O,j++*2)+(f?O:'\\')+new string(' ',z)+'/';}return o;}

Originalmente tenía el new string(...)como un Func<char,int,string>byte guardado pero usando el constructor. Deseo int-> charestaba implícito

Estoy bastante seguro de que mis matemáticas también se pueden arreglar de alguna manera, pero no puedo verlo

pinkfloydx33
fuente
1
Puedes jugar al golf un poco más. En primer lugar se puede quitar el int antes z=añadiéndolo al bucle for-: int j=0,z. Y como usas stringbastante, puedes usar un alias para que using s=System.String;el total sea: using s=System.String;s f(int N){var f=N<0;N=N>0?N:-N;var o=new s('_',N*4);for(int j=0,z;j<N;){z=-2*j+2*N-2;var O=j>N-2?'_':' ';o+='\n'+new s(' ',j)+'\\'+new s(' ',z)+(f?'/':O)+new s(O,j++*2)+(f?O:'\\')+new s(' ',z)+'/';}return o;}( 231 bytes )
Kevin Cruijssen
1

Swift 2.2 421 bytes

Bueno ... Esto fue un intento.

Golfizado:

let t={(s:String,n:Int)->String in return String(count:n,repeatedValue:Character(s))};let e={(n:Int)in var w=[String]();w.append(t("_",abs(n)*4));let c = abs(n);let d = n>0 ? "/": "\\";let f = n>0 ? "\\": "/";for var i in 0...abs(n)-1 {w.append(t(" ",i)+d+t(" ",c*2-2-(2*i))+f+(i<c-1 ?t(" ",2*c-1)+f:t("_",2*c-1)+f)+(n>0 ?t(" ",i):""));};w=n<0 ?w:w.map(){String($0.characters.reverse())};print(w.joinWithSeparator("\n"))}

Sin golf:

let t={(s:String,n:Int) -> String in
    return String(count:n,repeatedValue:Character(s))
};
let e={(n:Int) in
    var w=[String]();
    w.append(t("_",abs(n)*4));
    let c = abs(n);
    let d = n>0 ? "/": "\\";
    let f = n>0 ? "\\": "/";
    for var i in 0...abs(n)-1 {
        w.append(t(" ",i)+d+t(" ",c*2-2-(2*i))+f+(i<c-1 ?t(" ",2*c-1)+f:t("_",2*c-1)+f)+(n>0 ?t(" ",i):""));
    };
    w=n<0 ?w:w.map(){String($0.characters.reverse())};
    print(w.joinWithSeparator("\n"))
}
Danwakeem
fuente
1

PHP, 143 bytes

$t=str_repeat;echo$t(_,4*$s=$k=abs($n=$argv[1]));for(;$k--;$p.=" "){$f=$t("  ",$k);$r=$t($k?" ":_,2*$s-1);echo"
$p\\",$n<0?"$f/$r/":"$r\\$f/";}

corre con php -r '<code>' <parameter>

Descompostura

$t=str_repeat;  // function name to variable saves 10-1 bytes
echo$t(_,4*$s=$k=abs($n=$argv[1])); // print bottom
for(
    ;
    $k--;   // $k from abs($n-1) to 0
    $p.=" "                 // create padding
)
{
    $f=$t("  ",$k);         // create front
    $r=$t($k?" ":_,2*$s-1); // create side/roof
    echo"\n$p\\",$n<0
        ?"$f/$r/"   // print, entrance left
        :"$r\\$f/"  // print, entrance right
    ;
}
Titus
fuente
1

Lote, 289 bytes

@echo off
set/pn=
set u=
for /l %%i in (2,1,%n:-=%)do call set u=_%%u%%_
echo _%u%__%u%_
set l=
set m=%u%/_%u%
if %n% gtr 0 set m=%u%_\%u%
set m=%m:_= %
for /l %%i in (2,1,%n:-=%)do call:l
set m=%m: =_%
:l
echo %l%\%m%/
set l= %l%
if %n% gtr 0 set m=  %m:~0,-2%
set m=%m:~2%

Toma entrada en STDIN. Comienza creando una cadena de 2*(abs(n)-1)guiones bajos. Esto se repite más 4 guiones bajos adicionales para la base de la tienda. El resto de la tienda consiste en una sangría (que aumenta en 1 en cada línea), a \, el centro de la tienda y a /. El centro de la tienda comienza como 2*(abs(n)-1)espacios, más uno \o /más un espacio (que no puedo representar en Markdown), más otros 2*(abs(n)-1)espacios. Reutilizo la cadena de subrayado y la cambio a espacios por conveniencia, pero luego cambio los espacios a guiones bajos para la última línea. Cada línea elimina dos espacios de un lado del centro de la tienda, aunque es un poco más golfista mover los dos espacios al inicio de la cuerda primero si es necesario.

Neil
fuente