Classic VCS ASCII Adventure


21

Al crecer, mi primer sistema de consola fue un Atari 2600 y siempre me encantarán algunos de esos juegos que tanto disfruté cuando era niño. Muchos de los gráficos siguen siendo memorables, quizás incluso icónicos.

Resulta que estos sprites son mapas de bits muy simplistas, de 8 píxeles de ancho con altura variable, donde la representación binaria es la disposición de los píxeles.

Por ejemplo, los bytes hexadecimales 0x18, 0x24, 0x18 dibujarían un círculo burdo así:

0x18: 00011000
0x24: 00100100
0x18: 00011000

Como 8 píxeles de ancho crea gráficos bastante pequeños (incluso para los estándares Atari 2600) era común duplicar o cuadruplicar la altura, el ancho o ambos para crear una versión más grande (aunque más bloqueada y distorsionada) de la misma imagen. Comúnmente, también serían volteados vertical u horizontalmente para los sprites y campos de juego de los jugadores. El juego Combat es un buen ejemplo de esto.

El desafío es escribir código para mostrar estos sprites como "gráficos" en forma ASCII, incluida la capacidad de estirarlos o voltearlos verticalmente, horizontalmente o ambos. Esto debe ser en forma de programa completo o función invocable.

Entrada:

  • Una matriz de bytes, cada uno representando los bits horizontales para esa línea.
  • Un valor entero distinto de cero para cada dirección, horizontal y vertical que representa el factor de escala para esa dimensión.
  • Un valor negativo indica que la dimensión también debe invertirse a lo largo de su eje.

Salida:

  • Representación ASCII a STDOUT o una cadena separada por una nueva línea, utilizando un carácter de espacio para píxeles negros (0) y cualquier carácter imprimible que no sea espacio de su elección para píxeles blancos (1).

Datos de prueba:

bmp1 = [ 0x06, 0x0F, 0xF3, 0xFE, 0x0E, 0x04, 0x04, 0x1E, 0x3F, 0x7F, 0xE3, 0xC3, 0xC3, 0xC7, 0xFF, 0x3C, 0x08, 0x8F, 0xE1, 0x3F ]
bmp2 = [ 0x07, 0xFD, 0xA7 ]
bmp3 = [ 0x00, 0x8E, 0x84, 0xFF, 0xFF, 0x04, 0x0E, 0x00 ]
bmp4 = [ 0x00, 0xFC, 0xFC, 0x38, 0x3F, 0x38, 0xFC, 0xFC]

Nota: Las matrices de entrada de bytes del ejemplo anterior se proporcionan como hexadecimales. Si su plataforma no acepta literales hexadecimales para la representación de bytes, puede convertirlos a un literal nativo equivalente a bytes.

Salida de ejemplo:

f( bmp1, 1, 1 ) =>
--------
     XX 
    XXXX
XXXX  XX
XXXXXXX 
    XXX 
     X  
     X  
   XXXX 
  XXXXXX
 XXXXXXX
XXX   XX
XX    XX
XX    XX
XX   XXX
XXXXXXXX
  XXXX  
    X   
X   XXXX
XXX    X
  XXXXXX
--------

f( bmp1, -2, 1 ) =>
----------------
  XXXX          
XXXXXXXX        
XXXX    XXXXXXXX
  XXXXXXXXXXXXXX
  XXXXXX        
    XX          
    XX          
  XXXXXXXX      
XXXXXXXXXXXX    
XXXXXXXXXXXXXX  
XXXX      XXXXXX
XXXX        XXXX
XXXX        XXXX
XXXXXX      XXXX
XXXXXXXXXXXXXXXX
    XXXXXXXX    
      XX        
XXXXXXXX      XX
XX        XXXXXX
XXXXXXXXXXXX    
----------------

f( bmp2, 1, 2 ) =>
--------
     XXX
     XXX
XXXXXX X
XXXXXX X
X X  XXX
X X  XXX
--------

f( bmp2, 2, 1 ) =>
----------------
          XXXXXX
XXXXXXXXXXXX  XX
XX  XX    XXXXXX
----------------

f( bmp2, -2, -2 ) =>
----------------
XXXXXX    XX  XX
XXXXXX    XX  XX
XX  XXXXXXXXXXXX
XX  XXXXXXXXXXXX
XXXXXX          
XXXXXX          
----------------

f( bmp3, 1, -1 ) =>
--------

    XXX 
     X  
XXXXXXXX
XXXXXXXX
X    X  
X   XXX 

--------

f( bmp3, 3, 3 ) =>
------------------------



XXX         XXXXXXXXX   
XXX         XXXXXXXXX   
XXX         XXXXXXXXX   
XXX            XXX      
XXX            XXX      
XXX            XXX      
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
               XXX      
               XXX      
               XXX      
            XXXXXXXXX   
            XXXXXXXXX   
            XXXXXXXXX   



------------------------

f( bmp4, -1, -1 ) =>
--------
  XXXXXX
  XXXXXX
   XXX  
XXXXXX  
   XXX  
  XXXXXX
  XXXXXX

--------

f( bmp4, 4, 2 ) =>
--------------------------------


XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
        XXXXXXXXXXXX            
        XXXXXXXXXXXX            
        XXXXXXXXXXXXXXXXXXXXXXXX
        XXXXXXXXXXXXXXXXXXXXXXXX
        XXXXXXXXXXXX            
        XXXXXXXXXXXX            
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
--------------------------------

Nota: las líneas horizontales arriba y abajo deben mostrar el comienzo y el final de la salida. No se requieren en la salida, sin embargo, se requieren líneas vacías (representadas por todos los ceros / espacios) al principio y / o al final, como se muestra.

Nota 2: estos mapas de bits de prueba se inspiraron y se volvieron a dibujar / codificar en base a capturas de pantalla del juego etiquetadas como "uso justo" en Wikipedia.

Criterios ganadores

  • Este es el , por lo que gana el código más corto en bytes por idioma.
  • Las lagunas estándar están prohibidas.

66
"¡Que alguien me quite este pato!" - Strong Bad
AdmBorkBork

77
La ironía es que incluso el golf más inteligente aquí probablemente no sea tan inteligente como lo que los programadores para el Atari 2600 realmente tenían que hacer si querían algo más interesante que un clon de Pong: toda la pantalla se mostraba una línea a la vez y el La CPU pasó la mayor parte de su tiempo haciendo eso. Con solo 128 bytes de RAM, no había lugar para un lujo como un búfer de pantalla ... Los cinco sprites completos que obtuviste fueron el lujo.
Jeroen Mostert

¿Podemos tomar la entrada como una lista de cadenas binarias de 8 bits o formatos similares donde los bytes ya están descomprimidos en bits?
Luis Mendo

@LuisMendo " Si su plataforma no acepta literales hexadecimales para la representación de bytes, puede convertirlos a un literal nativo equivalente a bytes " .
Kevin Cruijssen

@KevinCruijssen Ese es el punto, no sé qué se acepta como equivalente . ¿Eso abre la puerta para ingresar el mapa de bits directamente?
Luis Mendo

Respuestas:



5

05AB1E , 27 26 bytes

εS²Ä×J³Äи²0‹ií]³0‹iR}˜0ð:»

Toma la entrada como una lista de cadenas binarias de 8 bits y las salidas con un carácter 1no espacial.

-1 byte gracias a @MagicOctopusUrn .

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

ε         # Map the (implicit) input-list to:
 S        #  Convert the binary-String to a list of characters
  ²Ä      #  Take the absolute value of the second input
    ×     #  And repeat each character that many times
     J    #  And then join it back together to a single string again
 ³Ä       #  Take the absolute value of the third input
   и      #  Repeat that string as a list that many times
 ²0i     #  If the second input is negative:
     í    #   Reverse each string in the list
]         # Close both the if-statement and (outer) map
³0i }    # If the third input is negative:
    R     #  Reverse the list of lists
      ˜   # Flatten the list of lists to a list of strings
0ð:       # Replace all 0s with spaces " "
   »      # And join the strings by newlines (which is output implicitly)

Tiene que haber un 2-byter para 0‹i...
Urna de pulpo mágico

@MagicOctopusUrn Debería haber un byte para, de 0‹hecho ... Tenemos un byte para >=0, que es d. Pero también deberíamos tener un 1 byter para verificar la imo negativa. Ahora solo uso 0‹o d_.
Kevin Cruijssen

Todo lo que se me ocurrió fue: „íR³²‚0‹Ï.V(código completo εε²Ä×}J³Äи0ð:}„íR³²‚0‹Ï.V˜») que no es una mejora, pero elimina uno de esos controles negativos.
Urna de pulpo mágico

1
Además, bastante seguro εS²Ä×J³Äи²0‹ií]³0‹iR}˜0ð:»guarda un byte. Si puede tomar una matriz 2D, puede eliminarla Spor completo por 25 bytes.
Urna de pulpo mágico

@MagicOctopusUrn Ah, por supuesto, en S²Ä×lugar de ε²Ä×}. ¡Gracias! Hmm, si se nos permite tomar las entradas binarias como una lista de 0s y 1s, se podría guardar un byte adicional omitiendo el S. Le preguntará a OP si esto está permitido. Me gusta tu „íR³²‚0‹Ï.Ven tu otro comentario también. :)
Kevin Cruijssen

3

MATL , 24 19 bytes

B,!i|1&Y"2M0<?XP]Zc

Las entradas son una matriz de números decimales, escala horizontal, escala vertical.

Pruébalo en línea!

Explicación

B        % Implicit input: array of numbers. Convert to binary. Gives a zero-one
         % matrix, each row containing the binary expansion of a number
,        % Do twice
  !      %   Transpose
  i      %   Input: number
  |      %   Absolute value
  1&Y"   %   Repeat each row that many times
  2M     %   Push the latest input again
  0<     %   Is it negative?
  ?      %   If so:
    XP   %     Flip vertically
  ]      %   End
  Zc     %   Convert each nonzero into '#'. Zeros are displayed as space
         % Implicit end. Implicit display

3

Dyalog APL, 46 42 33 bytes

' #'[⍉⊃{⊖⍣(0>⍺)⍉⍵/⍨|⍺}/⎕,⊂⎕⊤⍨8/2]

Pruébalo en línea!

-9 gracias a ngn!


cada -> reducir: {' #'[⊃{⌽⍣(0>⍺)⊢(|⍺)/⍉⍵}/⍺,⊂⍉⍵⊤⍨8/2]}dfn -> programa:' #'[⊃{⌽⍣(0>⍺)⊢(|⍺)/⍉⍵}/⎕,⊂⍉⎕⊤⍨8/2]
ngn

más corto: ' #'[⍉⊃{⊖⍣(0>⍺)⍉⍵/⍨|⍺}/⎕,⊂⎕⊤⍨8/2]. por cierto, la salida para la segunda prueba parece invertida en su solución original
ngn

@ngn gracias! las entradas para el segundo ejemplo deberían haberse invertido para coincidir con el segundo caso de prueba en la pregunta.
dzaima

3

Prólogo (SWI) , 252 bytes

N+E+R:-N<1,R=[];N-1+E+S,R=[E|S].
N*E*R:-R=E,E=[];N<0,reverse(E,F),-N*F*R;[H|T]=E,N+H+S,N*T*U,append(S,U,R).
N/E/R:-N<1,R=[];(E<N,D=E,F=32;D=E-N,F=35),N/2/D/C,R=[F|C].
[H|T]^X^Y^R:-128/H/A,X*A*B,Y*[[10|B]]*C,append(C,D),(T=[],R=D;T^X^Y^S,append(D,S,R)).

Pruébalo en línea!

Explicación

N+E+R:-N<1,R=[];N-1+E+S,R=[E|S].   Make `R` a list containing `E` repeated `N` times
       N<1,R=[]                    If `N<1`, let `R` be the empty list
       N-1+E+S                     Else recurse with `N-1`, `E` and `S`
           R=[E|S]                 Let `R` be a new list with `E` as head and `S` as tail
N*E*R:-R=E,E=[];N<0,reverse(E,F),-N*F*R;[H|T]=E,N+H+S,N*T*U,append(S,U,R).
                                   Let `R` be a list
                                   with each element in `E` repeated `N` times
                                   e.g. 2*[3, 6] -> [3, 3, 6, 6]
       R=E,E=[]                    Let `R` be `E` if `E` is the empty list
       N<0,reverse(E,F)            Else if `N<0`, let `F` be the reverse of `E`
           -N*F*R                  Recurse with `-N`, `F` and `R`
       [H|T]=E                     Else let `H` be the head and `T` be the tail of `E`
           N+H+S                   Let `S` be `N+H+S` (our function, not addition)
           N*T*U                   Recurse with `N`, `T` and `U`
           append(S,U,R)           let `R` be the concatenation of `S` and `U`
N/E/R:-N<1,R=[];(E<N,D=E,F=32;D=E-N,F=35),N/2/D/C,R=[F|C].
                                   Make `R` the binary representation of `E`
                                   with `N` as the value of the current bit
                                   where 0 and 1 are space and hash respectively
    N<1,R=[]                       If `N<1` let `R` be the empty list
    (
        E<N,D=E,F=32               If `E<N` the bit isn't set, so `D=E`, `F=space`
        D=E-N,F=35                 Else `D=E-N`, `F=hash`
    )
        N/2/D/C                    Recurse with `N/2`, `D` and `C`
        R=[F|C]                    Let `R` be a new list with `F` as head and `C` as tail
[H|T]^X^Y^R:-128/H/A,X*A*B,Y*[[10|B]]*C,append(C,D),(T=[],R=D;T^X^Y^S,append(D,S,R)).
                                   Make `R` the result,
                                   with inputs being the list `[H|T]`
                                   and the scales `X` and `Y`
   128/H/A                         Let `A` be the binary representation of `H` (8 bits)
   X*A*B                           Let `B` be `A` with each element repeated `X` times
   Y*[[10|B]]*C                    Let `C` be `B` with a newline prepended,
                                   repeated `Y` times
   append(C,D)                     Let `D` be `C` flattened by one level (joining lines)
   (
       T=[],R=D                    If `T` is empty, let `R` be `D` 
       T^X^Y^S                     Else recurse with `T`, `X`, `Y` and `S`
           append(D,S,R)           Let `R` be the concatenation of `D` and `S`
   )

2

Carbón , 28 bytes

FθE↔ζ⭆⮌↨ι²×§ Xμ↔ηF›η⁰‖F‹ζ⁰‖↓

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

Fθ

Recorrer la lista de bytes.

E↔ζ

Mapa sobre el factor de escala vertical, multiplicando así las líneas de salida.

⭆⮌↨ι²×§ Xμ↔η

Convierta la entrada a la base 2, inviértala, asigne los dígitos al espacio y Xluego multiplique cada carácter por el factor de escala horizontal.

F›η⁰‖

Si el factor de escala horizontal fue positivo, reflexione para obtener la imagen de la forma correcta nuevamente.

F‹ζ⁰‖↓

Refleje verticalmente si el factor de escala vertical fue negativo.


No es que ahorre bytes, pero tengo curiosidad: ¿por qué usaste F( For) en lugar de ¿( If) para las comprobaciones?
Kevin Cruijssen

1
@KevinCruijssen En modo sucinto de carbón, elseestá implícito, por lo que el único momento que puedo usar ifes si es la última declaración en el bloque.
Neil

Ah ok, no sabía sobre eso. Por lo tanto, usar dos Ifaquí sería en realidad un If ... Else If ...flojo en lugar de dos If. Hmm, es bueno saberlo.
Kevin Cruijssen


2

Lisp común , 157 bytes

(lambda(l x y)(dolist(i(if(< y 0)(reverse l)l))(dotimes(j(abs y))(dotimes(n 8)(dotimes(k(abs x))(princ(if(logbitp(if(< x 0)n(- 7 n))i)"#"" "))))(princ"
"))))

Pruébalo en línea!

Explicación

(lambda(l x y)                           ; Lambda with parameters `l`, `x`, `y`
    (dolist
        (i                               ; For `i` in the list  
            (if(< y 0)(reverse l)l)      ; The reverse of `l` if `y<0` else `l`
        )
        (dotimes(j(abs y))(dotimes(n 8)(dotimes(k(abs x))
                                         ; Do `y` times, for `n` from 0 to 7, do `x` times
        (princ(if(logbitp(if(< x 0)n(- 7 n))i)"#"" "))))
                                         ; If `x<0` and the `n`th bit is 1
                                         ; or `x>0` and the `7-n`th bit is 1
                                         ; print "#", else print " "
        (princ"
")                                       ; After every `y` loop, print a newline
        )
    )
)

2

Tcl , 192 bytes

proc f {l x y} {lmap i [if $y<0 {lreverse $l} {lindex $l}] {time {lmap n {0 1 2 3 4 5 6 7} {time {puts -nonewline [expr $i&1<<($x<0?$n:7-$n)?{#}:{ }]} [expr abs($x)]};puts {}} [expr abs($y)]}}

Pruébalo en línea!

proc f {l x y}                           Define a function `f` with arguments `l`, `x`, `y`
{lmap i                                  For each `i` in
    [if $y<0 {lreverse $l} {lindex $l}]  The reverse of `l` if `y<0` else `l`
    {
        time {                           Do `abs(y)` times
            lmap n {0 1 2 3 4 5 6 7} {   For `n` from 0 to 7
                time {                   Do `abs(x)` times
                    puts -nonewline      Print without newline
                         [expr $i&1<<($x<0?$n:7-$n)?{#}:{ }]
                                         If `x<0` and the `n`th bit is 1 or
                                         `x>0` and the `7-n`th bit is 1
                                         then return "#" else return " "
                } [expr abs($x)]
            };
            puts {}                      Print a newline
        } [expr abs($y)]
    }
}

2

Código de máquina 8088, IBM PC DOS, 77 71 bytes

Montado:

B402 84FF 7906 FD03 F14E F6DF 518A CFAC 5051 B108 8AF3 84F6 7902 F6DE
518A CEB2 2384 DB79 04D0 C8EB 02D0 C072 02B2 2050 CD21 58E2 FA59 E2E4
B20D CD21 B20A CD21 5958 E2CC 59E2 C5

Listado:

    PR_BMP  MACRO BMP, SZBMP, ZX, ZY
            LOCAL LOOP_Y, LOOP_Y2, LOOP_X, LOOP_X2, X_POS, X_NEG
B4 02   MOV  AH, 2          ; DOS display char function 
84 FF   TEST ZY, ZY         ; is Y scale negative?
79 06   JNS  LOOP_Y         ; if positive, start Y LOOP
FD      STD                 ; direction flag start from end
03 F1   ADD  BMP, CX        ; advance input byte array to end
4E      DEC  BMP            ; zero adjust index
F6 DF   NEG  ZY             ; make counter positive
     LOOP_Y:    
51      PUSH CX             ; save outer byte loop counter
8A CF   MOV  CL, ZY         ; set up repeat counter (Y scale factor)
AC      LODSB               ; load byte into AL
     LOOP_Y2:
50      PUSH AX             ; save original AL
51      PUSH CX             ; save outer loop
B1 08   MOV  CL, 8          ; loop 8 bits
8A F3   MOV  DH, ZX         ; DH is positive X scale used as counter
84 F6   TEST ZX, ZX         ; is X scale negative?
79 02   JNS  LOOP_X         ; if so, make counter positive
F6 DE   NEG  DH             ; compliment X counter 
    LOOP_X:
51      PUSH CX             ; save bit counter
8A CE   MOV  CL, DH         ; set repeat counter (X scale factor)
B2 23   MOV  DL, '#'        ; by default, display a #
84 DB   TEST ZX, ZX         ; is X scale negative?
79 04   JNS  X_POS          ; if so, rotate left 1 bit
D0 C8   ROR  AL, 1          ; else rotate right LSB into CF
EB 02   JMP  X_NEG          ; jump to examine CF
    X_POS:
D0 C0   ROL  AL, 1          ; rotate left MSB into CF
    X_NEG:
72 02   JC   LOOP_X2        ; is a 1?   
B2 20   MOV  DL, ' '        ; if not, display a space
    LOOP_X2:    
50      PUSH AX             ; save AL (since silly DOS overwrites it)
CD 21   INT  21H            ; display char
58      POP  AX             ; restore AL
E2 FA   LOOP LOOP_X2        ; loop repeat counter
59      POP  CX             ; restore bit counter
E2 E4   LOOP LOOP_X         ; loop bit counter
B2 0D   MOV  DL, 0DH        ; display CRLF
CD 21   INT  21H
B2 0A   MOV  DL, 0AH
CD 21   INT  21H
59      POP  CX             ; restore outer loop
58      POP  AX             ; restore original AL
E2 CC   LOOP LOOP_Y2        ; loop row display
59      POP  CX             ; restore byte counter
E2 C5   LOOP LOOP_Y         ; loop byte counter
    ENDM

Esto resultó ser más deslumbrante en ASM de lo que originalmente pensé. Múltiples bucles concurrentes y muchas ramificaciones if / else ciertamente pueden causar dolores de cabeza.

Esto se implementa como un MACRO ya que permite el paso de parámetros similares a funciones para pruebas.

Salida

Aquí hay un programa de prueba para DOS que solicita el factor de escala X e Y y se dibuja en la pantalla. Tenga en cuenta que escalar demasiado el dragón se desplazará más allá de la parte superior, ya que la ventana predeterminada de DOS solo tiene 24 filas.

ingrese la descripción de la imagen aquí

Y aquí está nuestro pequeño dragón (pato):

ingrese la descripción de la imagen aquí

Pruébalo en línea!

Puede probar en una máquina virtual DOS con DOSBox o VirtualConsoles.com con los siguientes pasos:

  1. Descargar VCS.ZIP (contiene los cuatro ejecutables)
  2. Vaya a https://virtualconsoles.com/online-emulators/DOS/
  3. Cargue el archivo ZIP que acaba de descargar, haga clic en Inicio
  4. Escribir PLANE, KEY, TANKo DRAGON.

1

Perl 5, 105 bytes

($_,$h,$v)=@F;say for map{$_=reverse if$h<0;y/0/ /;s/./$&x abs$h/eg;($_)x abs$v}$v<0?reverse/\d+/g:/\d+/g

TIO

Si la entrada debe ser hexadecimal

126 bytes



1

APL (Dyalog Extended) , SBCS de 23 bytes

método de dzaima

(v,h,B)vhB⎕IO←0

' x'⊇⍨∘⊃{⊖⍣(>⍺)⍉⍵/⍨|⍺}/

Pruébalo en línea!

{}/ Reduzca de derecha a izquierda utilizando la siguiente lambda anónima:

|⍺ La magnitud del argumento izquierdo (el factor de escala)

⍵/⍨ usar eso para replicar el argumento correcto horizontalmente

 transponer

⊖⍣(... ) voltear si:

  >⍺ el factor de escala es menor que cero

 revelar (ya que la reducción incluida para reducir el rango del tensor de 1 a 0)

' x'⊇⍨ seleccionar elementos de la cadena "x" usando esa matriz



1

T-SQL, 216 bytes

Antes de ejecutar este MS-SQL Studio Management, presione CRTL-t para mostrar los datos como texto. La altura no se puede ajustar para exceder el número de elementos en la entrada.

Debido a la horrible implementación de STRING_AGG , la variable de altura solo funcionará en MSSM. MS debería haber hecho un tercer parámetro opcional para incluir el orden de los elementos que se concatenan.

La versión en línea solo puede soportar el ajuste del ancho. La altura dará como resultado un resultado funky con múltiples formas de apilamiento.

USE master
DECLARE @ table(v int,i int identity)
INSERT @ values
(0x06),(0x0F),(0xF3),(0xFE),(0x0E),(0x04),
(0x04),(0x1E),(0x3F),(0x7F),(0xE3),(0xC3),
(0xC3),(0xC7),(0xFF),(0x3C),(0x08),(0x8F),
(0xE1),(0x3F)
-- @  = width
-- @h = height
DECLARE @s INT=1,@h INT=1

SELECT iif(@s>0,reverse(x),x)FROM(SELECT
string_agg(replicate(iif(v&n=0,' ','X'),abs(@s)),'')x,i,j
FROM(values(1),(2),(4),(8),(16),(32),(64),(128))x(n)
,@,(SELECT top(abs(@h))i j FROM @)g GROUP BY i,j)f
ORDER BY i*@h

Este script no mostrará las formas correctas en la versión en línea, así que hice algunos ajustes menores para compensar. Pruébalo en línea

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.