Estanterías ASCII


27

¿Conoces los estantes apilables que son básicamente cajas de madera que se pueden apilar juntas? Vamos a simular la construcción de algunas estanterías de libros con arte ASCII.

Nuestros libros tienen un tamaño convenientemente uniforme, y todos se parecen a lo siguiente:

|X|
|X|
|X|

Las estanterías son cajas individuales, siempre con tres caracteres de altura en el interior (lo suficiente como para que quepa un libro en posición vertical), compuestas de |caracteres a la izquierda y a la derecha, -caracteres para la parte superior e inferior y lo suficientemente anchas para caber en los Xlibros (donde Xhay una entrada entero). Por ejemplo, aquí hay una estantería de tamaño 3:

|---------|
|         |
|         |
|         |
|---------|

porque puedes meter 3libros así

|---------|
||X||X||X||
||X||X||X||
||X||X||X||
|---------|

La entrada será dos enteros estrictamente positivos Xy Ydónde Xestá el ancho de los estantes que tenemos (medidos en libros) y Ycuántos libros tenemos que apilar. Si tenemos más libros que los que caben en un solo estante, necesitamos agregar más estantes en la parte superior. Por ejemplo, aquí está la entrada 4 wide / 6 books:

|------------|
||X||X|      |
||X||X|      |
||X||X|      |
|------------|
|------------|
||X||X||X||X||
||X||X||X||X||
||X||X||X||X||
|------------|

Si Y % X > 0, lo que significa que el número de libros no es un múltiplo entero del tamaño del estante, los libros restantes deben ir en la posición superior izquierda más (como en el caso con 4 6, arriba) y la parte restante de ese estante llena con espacios

Entrada

  • Dos enteros estrictamente positivos en cualquier formato conveniente , cada uno >0.
  • Puede tomar la entrada en cualquier orden (por ejemplo, primero el tamaño de los estantes, luego el número de libros o viceversa). Indique en su envío el orden de entrada.
  • Puede suponer con seguridad que ninguna de las entradas será mayor que el [int]tamaño predeterminado de su idioma (o equivalente).

Salida

La representación artística ASCII resultante de los libros y estanterías.

Reglas

  • Las nuevas líneas o espacios en blanco iniciales o finales son opcionales, siempre que los caracteres se alineen correctamente.
  • Un programa completo o una función son aceptables. Si es una función, puede devolver el resultado en lugar de imprimirlo.
  • Si es posible, incluya un enlace a un entorno de prueba en línea para que otras personas puedan probar su código.
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).

Ejemplos adicionales

6 wide / 2 books
|------------------|
||X||X|            |
||X||X|            |
||X||X|            |
|------------------|

2 wide / 6 books
|------|
||X||X||
||X||X||
||X||X||
|------|
|------|
||X||X||
||X||X||
||X||X||
|------|
|------|
||X||X||
||X||X||
||X||X||
|------|

4 wide / 9 books
|------------|
||X|         |
||X|         |
||X|         |
|------------|
|------------|
||X||X||X||X||
||X||X||X||X||
||X||X||X||X||
|------------|
|------------|
||X||X||X||X||
||X||X||X||X||
||X||X||X||X||
|------------|

¿Puedo hacerlo para que el estante con la menor cantidad de libros esté en la parte inferior, de modo que se llene de arriba a abajo
Golden Ratio

1
@GoldenRatio No, los libros deben llenarse de abajo hacia arriba, de izquierda a derecha.
AdmBorkBork

Respuestas:


14

JavaScript (ES6), 100 99 98 bytes

Toma el ancho wy el número de libros ben sintaxis curry (w)(b).

w=>g=(b,s=`|${'-'.repeat(w*3)}|
`,r=s.replace(/---/g,_=>b&&b--?'|X|':'   '))=>(b?g(b)+s:s)+r+r+r+s

Formateado y comentado

w =>                                // main function: takes width 'w' as input, returns 'g'
  g = (                             // g = recursive function with:
    b,                              //   - b = number of books
    s = `|${'-'.repeat(w * 3)}|\n`, //   - s = top/bottom of shell, filled with '-'
    r = s.replace(                  //   - r = pattern of the current row of books,
      RegExp('---', 'g'),           //         using 's' as a template and updating
      _ => b && b-- ? '|X|' : '   ' //         'b' while building it
    )                               // NB: 'r' must be defined in the scope of 'g',
  ) =>                              //     otherwise it would be overwritten by
    (                               //     subsequent calls
      b ?                           // if there are remaining books:
        g(b) + s                    //   do a recursive call and append shell top
      :                             // else:
        s                           //   just append shell top
    ) + r + r + r + s               // append book rows and shell bottom

Casos de prueba


9

Bash (+ utilidades), 130, 108106 bytes

Una tubería única y continua para proyectar sus estanterías.

Registro de cambios:

  • Primera expresión sed optimizada un poco, -12 bytes (¡Thx @Riley!)
  • Reemplazado printf + seqcon un bruto printf, -10 bytes
  • Refactorizó la segunda expresión sed, -2 bytes

Golfed

printf %$2s\\n|fold -$1|sed "s/ /|X|/g;:;/.\{$[$1*3]\}/!s/$/ /;t;h;s/./-/gp;x;p;p;p;x"|sed 's/.*/|&|/'|tac

$./shelf 6 8
|------------------|
||X||X|            |
||X||X|            |
||X||X|            |
|------------------|
|------------------|
||X||X||X||X||X||X||
||X||X||X||X||X||X||
||X||X||X||X||X||X||
|------------------|

¡Pruébelo en línea!

Cómo funciona

$./shelf 2 3

printf %$2s\\n- generar n caracteres de espacio en blanco, uno por libro (como se muestra _)

___

fold -$1 - doblarlos por la longitud del estante

__
_

sed "s/ /|X|/g;"- reemplazar _con X, agregar portadas de libros

|X||X|
|X|

:;/.\{$[$1*3]\}/!s/$/ /;t- Almohadilla derecha con espacios (como se muestra _)

|X||X|
|X|___

h;s/./-/gp;x;p;p;p;x- triplicar cada línea y agregar ---antes y después.

------
|X||X|
|X||X|
|X||X|
------
------
|X|   
|X|   
|X|   
------

sed 's/.*/|&|/'|tac- envolver las líneas | |, invertir con tac

|------|
||X|   |
||X|   |
||X|   |
|------|
|------|
||X||X||
||X||X||
||X||X||
|------|

En el primer sed puedes usar una etiqueta sin nombre, y en tlugar de beso no necesitas la {}. Puede omitir el s/./-/gporque ya son -s. Pruébalo en línea!
Riley

@Riley Ese es un excelente consejo, ¡gracias!
zepelín

6

Python 2, 133 113 105 bytes

Estoy seguro de que hay una mejor manera ...

X,Y=input()
k='|'+'---'*X+'|'
while Y:g=Y%X or X;print k+'\n'+('|'+'|X|'*g+'   '*(X-g)+'|'+'\n')*3+k;Y-=g

Se toma entrada width, books

-20 bytes gracias a @ovs por notar una función lambda innecesaria.
-8 bytes gracias a @ovs por acortar la entrada.


X,Y=input()es una forma más corta de tomar los valores to.
Ovs

@ovs Oh, espera, lo puse allí para mi primer intento. Whoops Buena captura, gracias!
HyperNeutrino

1
@ovs Gracias, entonces la entrada se toma como X, Y, ¿verdad?
HyperNeutrino

2
Creo que puede guardar dos bytes definiéndolos '|'como una variable.
Ørjan Johansen el

6

Lote, 261 bytes

@set/an=~-%1%%%2+1,b=%1-n
@set s=
@set t=
@for /l %%i in (1,1,%2)do @call set t=---%%t%%&if %%i gtr %n% (call set s=%%s%%   )else call set s=%%s%%X
@for %%s in ("|%t%|" "|%s:X=|X|%|" "|%s:X=|X|%|" "|%s:X=|X|%|" "|%t%|")do @echo %%~s
@if %b% gtr 0 %0 %b% %2

Utiliza mi truco de mi respuesta Batch a Let's play tennis para imprimir fácilmente muchos |personajes.


5

Haskell , 100 bytes

x#ydevuelve la cadena de ancho xy ylibros.

s?n=[1..n]>>s
x#y|x<y=x#(y-x)++x#x|w<-"---"?x,b<-"|X|"?y++"   "?(x-y)=[w,b,b,b,w]>>=('|':).(++"|\n")

Pruébalo en línea!

La función / operador principal es #. Cuando x<ydivide los libros y-xy xluego vuelve a aparecer. Cuando x>=y, wy bson los dos tipos de líneas, menos los exteriores |s y la nueva línea.

El operador auxiliar s?nconcatena ncopias de la cadena s.


5

PowerShell , 149134 bytes

param($w,$b)$s="|$('-'*$w*3)|"
if($a=$b%$w){,$s+,"|$('|X|'*$a)$(' '*3*($w-$a))|"*3+$s}
if($b-=$a){(,$s+,"|$('|X|'*$w)|"*3+$s)*($b/$w)}

Pruébalo en línea!

Toma entrada $width y $books. Establece la cadena $scomo uno de los estantes horizontales. Entonces tenemos dos ifdeclaraciones.

El primero verifica si tenemos libros "restantes". Si es así, sacamos el estante, el (número de libros más el número de espacios) *3y otro estante.

A continuación, vemos si todavía tenemos libros restantes después de eliminar los restos ( $a). El mismo tipo de configuración, excepto que estamos usando $wvarios libros. Dado que en este punto, $bse garantiza que es un múltiplo de $w(porque eliminamos el resto $a), no debemos preocuparnos por el redondeo.

Se eliminó la [math]::Floor()llamada, ahorrando 15 bytes.

Todas estas cadenas se dejan en la tubería, y Write-Outputsucede implícitamente al finalizar el programa.


4

CJam , 62 61 bytes

q~1a*W$/W$f{0e]}{{"|X|"S3*?}%s__'-3*W$*_}%1m>W%"|
|"*"||"\*o;

Toma entrada como width books

Pruébalo en línea!

Explicación

q~           Read and eval input (pushes width W and books B to the stack)
1a*          Push an array containing  the number 1 B times
W$/          Split it into chunks of size W
W$f{0e]}     Pad each chunk to width W by adding 0's to the right (the last chunk might be 
              shorter than W)
{            Apply the following to each chunk:
 {            Apply the following to each number in the chunk:
  "|X|"S3*?    Push "|X|" if the number is 1, or "   " if it's 0
 }%           (end of block)
 s            Stringify (joins with no separator)
 __           Duplicate twice (each shelf is 3 identical lines)
 '-3*W$*_     Push a string containing '-' repeated 3×W times, then duplicate it
}%           (end of block)
              At this point we have an array containing sequences of 3 identical lines 
              each followed by two lines of -'s
1m>          Rotate the array 1 to the right; brings the final line of -'s to the start
W%           Reverse the array, so that the top shelf is the partially empty one
"|\n|"*      Join the array with the string "|\n|", to build the sides of the shelves
"||"\*       Join the string "||" with the shelf string (adds the first and last | chars)
o            Print the result
;            Pop and discard W

4

Python 3, 142 bytes

Sigo trabajando en eso. bes para 'número de libros' y wes para ancho de estantería.

def s(b,w):
 R=b%w
 B='|\n'
 I='|'
 X='|X|'
 d=I+3*w*'-'+B
 f=I+X*w+B
 p=I+R*X+3*(w-R)*' '+B
 print(R and d+3*p+d or" ")+b//w*(d+3*f+d))

Bienvenido a PPCG! Esto no funciona para mí a menos que R=b%wse mueva a la siguiente línea. Además, debería poder eliminar el espacio en blanco alrededor de esos tres =para guardar algunos bytes.
Business Cat

Bienvenido a PPCG!
AdmBorkBork

Puede reemplazar d+3*p+d if R!=0 else ''conR and d+3*p+d or''
shooqie

@shooqie Tengo curiosidad, ¿cómo podría esto evaluar el resultado d+3*p+d?
Juan Meleiro

1
Puede guardar algunos bytes colocando todas las definiciones en una línea usando punto y coma.
L3viathan

3

AHK, 208 bytes

AutoTrim,Off
w=%1%
b=%2%
f:=Mod(b,w)
Loop,%w%
s=%s%---
s=|%s%|`n
If (f>0) {
Loop,%f%
t=%t%|X|
Loop,% w-f
t=%t% ` ` `
t=|%t%|`n
t:=s t t t s
}
Loop,%w%
r=%r%|X|
r=|%r%|`n
Loop,% (b-f)/w
t:=t s r r r s
Send,%t%

Hay algunas cosas que me frustran aún más en el golf:

  • AutoHotkey no tiene una función de repetición incorporada
  • No puede usar directamente los argumentos pasados ​​( %1%& %2%) en las funciones matemáticas porque esperan la entrada de variable o número y asumirá que el no escapado 1es el número uno en lugar del nombre de la variable
  • No soy muy bueno jugando al golf

Una versión más fácil de leer de lo anterior se ve así:

AutoTrim,Off
w=%1%
b=%2%
f:=Mod(b,w)

Loop,%w%
   s=%s%---
s=|%s%|`n

If (f>0) {
   Loop,%f%
      t=%t%|X|
   Loop,% w-f
      t=%t% ` ` `
   t=|%t%|`n
   t:=s t t t s
}

Loop,%w%
   r=%r%|X|
r=|%r%|`n

Loop,% (b-f)/w
   t:=t s r r r s

Send,%t%

Si a Loopno usa corchetes {}, solo la siguiente línea es parte del bucle. Si establece el valor de una variable usando en :=lugar de =, puede eliminar los caracteres de escape de signo de porcentaje. Tilde n es el personaje de nueva línea.


3

Java 7, 230 224 222 bytes

String c(int w,int b){String r="",n="|\n",z="|";int i=0,j,k,t=b%w<1?w:b%w,x=b/w+(t!=w?1:0);for(;i++<w;z+="---");z+=n;for(i=0;i<x;i++){r+=z;for(j=0;j++<3;r+=n){r+="|";for(k=0;k<w;r+=i<1&k++>=t?"   ":"|X|");}r+=z;}return r;}

Explicación:

String c(int w, int b){                // Method with two integer parameters and String return-type
  String r = "",                       //  The return-String
         n = "|\n",                    //  Part that's used multiple times in the code
         z = "|";                      //  Shelf part of the book-boxes
  int i = 0, j, k,                     //  Indexes used in the for-loops
      t = b%w < 1 ? w : b%w,           //  Books on top shelf
      x = b/w + (t != w ? 1 : 0);      //  Amount of shelves
  for(; i++ < w; z += "---"); z += n;  //  Create the shelf-part ("|---|"; with w times "---")
  for(i = 0; i < x; i++){              //  Loop over the rows
    r += z;                            //   Append the result with the shelf-part
    for(j = 0; j++ < 3; ){             //   Loop three times (the height of the books & boxes)
      r += "|";                        //    Append the result-String with "|"
      for(k = 0; k < w;                //    Loop over the columns
          r +=                         //     And append the result-String with:
           i < 1                       //      If this is the first row:
           & k++ >= t ?                //      And the current column is larger or equal to the amount of books in the top shelf
             "   "                     //       Use an empty space
           :                           //      Else:
             "|X|"                     //       Use the book-part
            );                         //    End of columns loop
         r += n;                       //    Append the result-String with a "|" and a new-line
       }                               //   End of the loop of three
      r += z;                          //   Append the result-String with the shelf-part
    }                                  //  End of rows loop
    return r;                          //  Return the result-String
 }                                     // End of method

Código de prueba:

Pruébalo aquí

class M{
  static String c(int w,int b){String r="",n="|\n",z="|";int i=0,j,k,t=b%w<1?w:b%w,x=b/w+(t!=w?1:0);for(;i++<w;z+="---");z+=n;for(i=0;i<x;i++){r+=z;for(j=0;j++<3;r+=n){r+="|";for(k=0;k<w;r+=i<1&k++>=t?"   ":"|X|");}r+=z;}return r;}

  public static void main(String[] a){
    System.out.println(c(6, 2));
    System.out.println(c(2, 6));
    System.out.println(c(4, 9));
  }
}

Salida:

|------------------|
||X||X|            |
||X||X|            |
||X||X|            |
|------------------|

|------|
||X||X||
||X||X||
||X||X||
|------|
|------|
||X||X||
||X||X||
||X||X||
|------|
|------|
||X||X||
||X||X||
||X||X||
|------|

|------------|
||X|         |
||X|         |
||X|         |
|------------|
|------------|
||X||X||X||X||
||X||X||X||X||
||X||X||X||X||
|------------|
|------------|
||X||X||X||X||
||X||X||X||X||
||X||X||X||X||
|------------|


@ OlivierGrégoire Teniendo en cuenta que publiqué esto hace aproximadamente 1,5 años, no me sorprende que se pueda jugar al golf de manera sustancial. ;)
Kevin Cruijssen

Ow ... no había comprobado la fecha: solo vi que esta pregunta estaba activa y que era posible un algoritmo completo para Java. My bad ...
Olivier Grégoire

@ OlivierGrégoire No hay problema, y ​​bien hecho con su respuesta. :) Casi se siente nostálgico mirar hacia atrás en esta respuesta cuando todavía estaba agregando los casos de prueba y la salida a la respuesta, y respondí todo en Java 7, porque todavía no entendía Java 8. XD
Kevin Cruijssen

2

PowerShell, 109 bytes

param($w,$b)for(;$b;$b-=$c){if(!($c=$b%$w)){$c=$w}($l="|$('-'*$w*3)|")
,"|$('|X|'*$c)$(' '*($w-$c)*3)|"*3
$l}

Menos guión de prueba de golf:

$f = {

param($w,$b)
for(;$b;$b-=$c){
    if(!($c=$b%$w)){$c=$w}
    ($l="|$('-'*$w*3)|")
    ,"|$('|X|'*$c)$(' '*($w-$c)*3)|"*3
    $l
}

}

@(
    ,(6, 2, 
    "|------------------|",
    "||X||X|            |",
    "||X||X|            |",
    "||X||X|            |",
    "|------------------|")

    ,(2, 6,
    "|------|",
    "||X||X||",
    "||X||X||",
    "||X||X||",
    "|------|",
    "|------|",
    "||X||X||",
    "||X||X||",
    "||X||X||",
    "|------|",
    "|------|",
    "||X||X||",
    "||X||X||",
    "||X||X||",
    "|------|")

    ,(4, 9,
    "|------------|",
    "||X|         |",
    "||X|         |",
    "||X|         |",
    "|------------|",
    "|------------|",
    "||X||X||X||X||",
    "||X||X||X||X||",
    "||X||X||X||X||",
    "|------------|",
    "|------------|",
    "||X||X||X||X||",
    "||X||X||X||X||",
    "||X||X||X||X||",
    "|------------|")
) | % {
    $w,$b,$expected = $_
    $result = &$f $w $b
    "$result"-eq"$expected"
    $result
}

Salida:

True
|------------------|
||X||X|            |
||X||X|            |
||X||X|            |
|------------------|
True
|------|
||X||X||
||X||X||
||X||X||
|------|
|------|
||X||X||
||X||X||
||X||X||
|------|
|------|
||X||X||
||X||X||
||X||X||
|------|
True
|------------|
||X|         |
||X|         |
||X|         |
|------------|
|------------|
||X||X||X||X||
||X||X||X||X||
||X||X||X||X||
|------------|
|------------|
||X||X||X||X||
||X||X||X||X||
||X||X||X||X||
|------------|

PowerShell, 109 bytes, alternativa

param($w,$b)for(;$b;$b-=$c){($l="|$('---'*$w)|")
,"|$('|X|'*($c=(($b%$w),$w-ne0)[0]))$('   '*($w-$c))|"*3
$l}

1

Python 2 , 120 118 bytes

i,j=input()
a=j%i
n='|\n'
x='|'+'---'*i+n
print(x+('|'+'|x|'*a+' '*(i-a)*3+n)*3,'')[a<1]+(x+('|'+'|x|'*i+n)*3)*(j/i)+x

Pruébalo en línea!

He tenido la intención de ir a este en los últimos días. Ahora que finalmente tengo tiempo para hacerlo, ya hay una respuesta Python más corta. Oh bueno, acabo de publicar como una alternativa.

Entrada tomada como ancho, libros


1

SOGL , 64 bytes

be%→M"Q└ƨS‘*ač;┼→S%‘A |e3* -* |++M?tMSeM-9*@*a+┼Ot}be÷:?{teSa┼Ot

Explicación: Primera función:

   →M  define function M which pushes
b      the book amount
  %    mod
 e     the bookshelf width

segunda función:

           →S  create function S (example input: 3)          [3]
"Q└ƨS‘         push the string "|||XXX|||" (the book)        [3, "|||XXX|||"]
      *        multiply by the number on stack (book count)  ["|||XXX||||||XXX||||||XXX|||"]
       a       push variable A (later defined "|||")         ["|||XXX||||||XXX||||||XXX|||", "|||"]
        č      chop into char array                          ["|||XXX||||||XXX||||||XXX|||", ["|", "|", "|"]]
         ;     swap top 2 on stack                           [["|", "|", "|"], "|||XXX||||||XXX||||||XXX|||"]
          ┼    horizontally append                           [["||X||X||X|", "||X||X||X|", "||X||X||X|"]]

Esta función espera un número (recuento de libros) en la pila y muestra los libros

["||X||X||X|",
 "||X||X||X|",
 "||X||X||X|"]

Más abajo, el ejemplo dado es e = 3 (ancho de estantería) yb = 8 (cantidad de libros)

%‘A              var A = "|||"                        
    |            push "|"                      ["|"]                
     e3*         push E * 3                    ["|", 9]             
         -*      push that many "-"es          ["|", "---------"]   
            |+   append "|"                    ["|", "---------|"]  
              +  prepend the "|"               ["|---------|"]      

esta es la línea superior / inferior de la estantería y siempre permanece en la primera parte de la pila (estantería medio vacía)

Primera parte principal

M?               }               if the modulo != 0
  tM                             output the bookshelf top/bottom line
    S                            execute the S function width the modulo
     eM-                         push bookshelf width - modulo (empty space count)
        9*                       multiply by 9 (books are 3x3 so 3x3 spaces)
          @*                     get that many spaces
            a+                   append to that "|||"
              ┼                  horizontally append
               O                 output
                t                output the bookshelf top/bottom line

Y la ultima parte

be÷            floor divide book amout by width (full shelves)
   :?          if not 0 (a bug makes all loops execute once)
     {         repeat
      t        output the bookshelf top/bottom line
       eS      execute S with shelf width (full shelf)
         a┼    horizontally append "|||"
           O   output
            t  output the bookshelf top/bottom line



0

Lienzo , 33 bytes.

|X|3*×⁷3×⇵-×|3*×╫│;22╋P
%?%⁸}÷[⁷⁸

Pruébalo aquí!

Explicación (algunos caracteres han sido reemplazados para parecer más monoespaciales):

|X|3*×⁷3×⇵-×|3*×╫│;22╋P  helper function. Prints a shelf with X books
|X|                      push "|X|"
   3*                    repeat it 3 times vertically
     ×                   repeat that horizontally by the item (X) below on the stack
      ⁷3×                push width * 3
         ⇵               ceiling divide that by 2
          -×             repeat "-" that many times
            |3*          repeat "|" vertically 3 times (aka "|¶|¶|")
               ×         prepend that to the dashes (aka ¼ of a bookshelf)
                ╫│       quad-palindromize with horizontal overlap of the remainder
                           taken before and vertical overlap of 1
                  ;      get the books on top
                   22╋   and at coordinates (2;2) in the shelf, place them in
                      P  print that whole thing

%?%⁸}÷[⁷⁸  
%?  }      if width%amount (!= 0)
  %⁸         execute the helper function with width%amount on the stack
     ÷[    repeat floor(width/amount) times
       ⁷     push width
        ⁸    execute the helper function

0

Pip -n , 45 bytes

Wb-:yPPZ['-X3Xa"|X|"X(Yb%a|a).sX3Xa-yRL3]WR'|

Toma el ancho y el recuento de libros, respectivamente, como argumentos de línea de comandos. Pruébalo en línea!

Explicación

Ejecutamos un bucle para imprimir los estantes uno por uno de arriba a abajo. En cada iteración, actualizamos b(la cantidad de libros para imprimir) restando y(la cantidad de libros impresos en esa iteración). Cuando bllega a 0, el ciclo sale.

Wb-:yPPZ['-X3Xa"|X|"X(Yb%a|a).sX3Xa-yRL3]WR'|
                                               a is 1st cmdline arg (shelf width); b is 2nd cmdline
                                                 arg (# books); s is space; y is ""
                                               Note that "" becomes zero in numeric contexts
Wb-:y                                          While b decremented by y is nonzero:
                       b%a|a                    b mod a, or a if that quantity is zero
                      Y                         Yank that value into y
                     (      )                   This is the number of books on the current shelf
               "|X|"                            Book-spine string
                    X                           Repeated y times
                                  a-y           Number of empty slots on the current shelf
                              sX3X              Three spaces for each slot
                             .                  Concatenate to the book-spines string
                                     RL3        Make a list of 3 copies of that string
         '-X3Xa                                 3*a hyphens
        [                               ]       Put that string and the above list in a list
                                         WR'|   Wrap all strings in the nested list in |
      PZ                                        Palindromize the outer list (adding a copy of the
                                                hyphens to the end of it)
     P                                          Print, joining all sublists on newlines (-n flag)

Porque eso es un poco complicado, aquí hay un ejemplo de la primera iteración cuando a = 3, b = 8:

Yb%a|a       2
"|X|"X ^     "|X||X|"
^ .sX3Xa-y   "|X||X|   "
^ RL3        ["|X||X|   ";"|X||X|   ";"|X||X|   "]
['-X3Xa ^ ]  ["---------";["|X||X|   ";"|X||X|   ";"|X||X|   "]]
^ WR'|       ["|---------|";["||X||X|   |";"||X||X|   |";"||X||X|   |"]]
PZ ^         ["|---------|";["||X||X|   |";"||X||X|   |";"||X||X|   |"];"|---------|"]

que luego se imprime como

|---------|
||X||X|   |
||X||X|   |
||X||X|   |
|---------|

0

Pyth , 56 bytes

M++GHGV_fTs*V,]Q1.DEQjCg*5\|smgL\-*L3?d"|X|""   ".[*]1N0

Acepta el ancho del estante, el recuento de libros como argumentos separados en ese orden. Pruébelo en línea aquí , o verifique todos los casos de prueba a la vez aquí .

M++GHGV_fTs*V,]Q1.DEQjCg*5\|smgL\-*L3?d"|X|""   ".[*]1N0Q   Implicit: Q=1st arg, E=2nd arg
                                                            Trailing Q inferred
M                                                           Define a function, g(G,H):
 ++GHG                                                        Return G + H + G
                 .DEQ                                       Divmod E by Q, yields [E//Q, E%Q]
             ,]Q1                                           [[Q], 1]
           *V                                               Vectorised multiply the two previous results
                                                              This yields Q repeated E//Q times, then E%Q
          s                                                 Flatten
        fT                                                  Filter out falsey values (i.e. trailing 0 if present)
       _                                                    Reverse (to put partially filled shelf on top)
      V                                                     For N in the above:
                                                    ]1        [1]
                                                   *  N       Repeat the above N times
                                                 .[    0Q     Pad the above on the right with 0, to length Q
                             m                                Map the above, as d, using:
                                     ?d"|X|""   "               If d != 0, yield "|X|", else "   "
                                  *L3                           Multiply each char by 3
                                                                  Yields ['|||','XXX','|||'] or ['   ','   ','   ']
                              gL\-                              Use g to wrap each element in '-'
                            s                                 Flatten
                       g*5\|                                  Use g to add '|||||' to start and end of the above
                      C                                       Transpose
                     j                                        Join on newlines, implicit print

0

Adelante (gforth) , 622 bytes (minimizado (eliminar comentarios, sangría, nombres de palabras de 1 carácter) a 303 bytes)

Mi primera jugada con Forth :)

: bar 124 EMIT ;

: delimline ( width -- )
    bar
    3 * 0 DO 45 EMIT LOOP
    bar CR
;

: bookline ( width books -- )
    bar
    DUP 0 DO bar 88 EMIT bar LOOP
    2DUP = IF
        DROP DROP
    ELSE
        - 0 do 3 SPACES LOOP
    THEN
    bar CR
;

: shelf ( width books -- )
    DUP 0 = IF
        DROP DROP
    ELSE
        OVER delimline
        3 0 DO OVER OVER bookline LOOP
        DROP delimline
    THEN
;

: stack ( width books -- )
    CR
    OVER OVER OVER MOD shelf
    OVER /
    DUP 0 = IF
        DROP DROP
    ELSE 
        0 DO DUP DUP shelf LOOP
    THEN
;

6 2 stack
2 6 stack
3 5 stack
4 4 stack

Pruébalo en línea!

Salida

| ------------------ |
|| X || X | El |
|| X || X | El |
|| X || X | El |
| ------------------ |

| ------ |
|| X || X ||
|| X || X ||
|| X || X ||
| ------ |
| ------ |
|| X || X ||
|| X || X ||
|| X || X ||
| ------ |
| ------ |
|| X || X ||
|| X || X ||
|| X || X ||
| ------ |

| --------- |
|| X || X | El |
|| X || X | El |
|| X || X | El |
| --------- |
| --------- |
|| X || X || X ||
|| X || X || X ||
|| X || X || X ||
| --------- |

| ------------ |
|| X || X || X || X ||
|| X || X || X || X ||
|| X || X || X || X ||
| ------------ |
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.