Estantes ASCII


27

Você conhece aquelas prateleiras empilháveis ​​que são basicamente caixas de madeira que podem ser empilhadas juntas? Vamos simular a construção de algumas estantes de livros com arte ASCII.

Todos os nossos livros são de tamanho convenientemente uniforme e têm a seguinte aparência:

|X|
|X|
|X|

As estantes de livros são caixas individuais, sempre com três caracteres de altura por dentro (o suficiente para acomodar um livro em pé), compostas por |caracteres à esquerda e à direita, -caracteres para a parte superior e inferior e suficientemente largas para acomodar Xlivros (onde Xé uma entrada inteiro). Por exemplo, aqui está uma estante de tamanho 3:

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

porque você pode colocar 3livros nela assim

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

A entrada será dois números inteiros estritamente positivos Xe Y, onde Xestá a largura das prateleiras que temos (medidas em livros) e Yé quantos livros temos para empilhar. Se temos mais livros do que cabem em uma única prateleira, precisamos adicionar mais prateleiras ao topo. Por exemplo, aqui está a entrada 4 wide / 6 books:

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

Se Y % X > 0, significando que o número de livros não é um múltiplo inteiro do tamanho da prateleira, os livros restantes devem ficar na posição mais à esquerda (como no caso 4 6acima) e a parte restante dessa prateleira preenchida com espaços.

Entrada

  • Dois números inteiros estritamente positivos em qualquer formato conveniente , cada um >0.
  • Você pode receber a entrada em qualquer ordem (por exemplo, tamanho das prateleiras primeiro, número de livros ou vice-versa). Indique no seu envio a ordem de entrada.
  • Você pode assumir com segurança que nenhuma das entradas será maior que o [int]tamanho padrão do seu idioma (ou equivalente).

Saída

A representação artística ASCII resultante dos livros e estantes.

Regras

  • Novas linhas à esquerda ou à direita ou espaços em branco são opcionais, desde que os próprios caracteres estejam alinhados corretamente.
  • Um programa completo ou uma função são aceitáveis. Se uma função, você pode retornar a saída em vez de imprimi-la.
  • Se possível, inclua um link para um ambiente de teste on-line para que outras pessoas possam experimentar seu código!
  • As brechas padrão são proibidas.
  • Isso é portanto todas as regras usuais de golfe se aplicam e o código mais curto (em bytes) vence.

Exemplos adicionais

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

Posso fazê-lo de modo a prateleira com a menor quantidade de livros está na parte inferior, assim como ele preenche cima para baixo
Golden Ratio

1
@GoldenRatio Não, os livros devem ser preenchidos de baixo para cima, da esquerda para a direita.
precisa saber é o seguinte

Respostas:


14

JavaScript (ES6), 100 99 98 bytes

Pega a largura we o número de livros bna sintaxe de 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

Formatado e 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 teste


9

Bash (+ utilitários), 130, 108, 106 bytes

Um pipeline de shell único e contínuo para renderizar suas estantes de livros.

Changelog:

  • Primeira expressão sed otimizada um pouco, -12 bytes (Thx @Riley!)
  • Substituído printf + seqpor um bruto printf, -10 bytes
  • Refatorou a segunda expressão sed, -2 bytes

Golfe

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

Experimente Online!

Como funciona

$./shelf 2 3

printf %$2s\\n- gerar n caracteres em branco, um por livro (mostrado como _)

___

fold -$1 - dobre-os pelo comprimento da prateleira

__
_

sed "s/ /|X|/g;"- substitua _por X, adicione capas de livros

|X||X|
|X|

:;/.\{$[$1*3]\}/!s/$/ /;t- teclado direito com espaços (mostrado como _)

|X||X|
|X|___

h;s/./-/gp;x;p;p;p;x- triplicar cada linha e adicionar ---antes e depois dela.

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

sed 's/.*/|&|/'|tac- enrole as linhas | |, inverta com tac

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

No primeiro sed, você pode usar um rótulo sem nome e, em tvez disso b, não precisa do {}. Você pode pular o arquivo s/./-/gporque eles já são -. Experimente Online!
Riley

@Riley Esse é um excelente conselho, obrigado!
Zeppelin #

6

Python 2, 133 113 105 bytes

Tenho certeza de que há uma maneira melhor ...

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

A entrada é recebida width, books

-20 bytes graças a @ovs por perceber uma função lambda desnecessária!
-8 bytes graças a @ovs por reduzir a entrada.


X,Y=input()é uma maneira mais curta de levar os valores a.
OVS

@ ohs Oh espere, eu coloquei isso lá na minha primeira tentativa. Ops. Boa captura, obrigado!
HyperNeutrino 02/03

1
@ovs Obrigado, então a entrada é tomada como X, Y, certo?
HyperNeutrino

2
Eu acho que você pode salvar dois bytes, definindo '|'como uma variável.
Ørjan Johansen

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 meu truque na resposta do Lote para Vamos jogar tênis para imprimir facilmente muitos |personagens.


5

Haskell , 100 bytes

x#yretorna a string para largura xe ylivros.

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

Experimente online!

A principal função / operador é #. Quando x<ydivide os livros em y-xe x, depois se repete. Quando x>=y, we bsão os dois tipos de linha, menos os exteriores |s e a nova linha.

O operador auxiliar s?nconcatena ncópias da sequência s.


5

PowerShell , 149 134 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)}

Experimente online!

Leva $width de entrada e OK $b. Define a string $scomo uma das prateleiras horizontais. Então nós temos duas ifafirmações.

O primeiro verifica se temos livros "restantes". Nesse caso, produzimos a prateleira, o (número de livros mais o número de espaços) *3e outra prateleira.

Em seguida, verificamos se ainda temos livros restantes após a remoção dos demais ( $a). O mesmo tipo de configuração, exceto que estamos usando o $wnúmero de livros. Como, neste ponto, $bé garantido um múltiplo de $w(porque removemos o restante $a), não precisamos nos preocupar com arredondamentos.

Removida a [math]::Floor()chamada, economizando 15 bytes

Todas essas seqüências são deixadas no pipeline e implícitas Write-Outputacontecem na conclusão do programa.


4

CJam , 62 61 bytes

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

Aceita entrada como width books

Experimente online!

Explicação

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

Ainda trabalhando nisso. bé para 'número de livros' e wé para a largura da prateleira.

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

Bem-vindo ao PPCG! Isso não funciona para mim, a menos que R=b%wseja movido para a próxima linha. Além disso, você deve poder remover o espaço em branco ao redor desses três =para salvar alguns bytes.
Business Cat

Bem-vindo ao PPCG!
AdmBorkBork #

Você pode substituir d+3*p+d if R!=0 else ''porR and d+3*p+d or''
shooqie 3/17/17

@shooqie Estou curioso, como isso pôde avaliar o resultado d+3*p+d?
Juan Meleiro

1
Você pode salvar alguns bytes colocando todas as definições em uma linha usando ponto e vírgula.
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%

Existem algumas coisas que me atrapalham com o golfe:

  • AutoHotkey não tem uma função de repetição interna
  • Você não pode usar diretamente os argumentos passados ​​( %1%& %2%) nas funções matemáticas, porque eles esperam entrada de variável ou número e assumirá que o não-escapado 1seja o número um em vez do nome da variável
  • Eu não sou muito bom em jogar golfe

Uma versão mais fácil de ler acima é assim:

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%

Se um Loopnão usar colchetes {}, apenas a próxima linha fará parte do loop. Se você definir o valor de uma variável usando em :=vez de =, poderá soltar os caracteres de escape do sinal de porcentagem. Tilde n é o caractere de nova linha.


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

Explicação:

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 do teste:

Experimente aqui.

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

Saída:

|------------------|
||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 Considerando que eu postei isso há cerca de 1,5 ano atrás, não estou surpreso que ele possa ser jogado de maneira substancial. ;)
Kevin Cruijssen 25/10

Ow ... eu não tinha verificado a data: vi apenas que essa pergunta estava ativa e que um outro algoritmo completo para Java era possível. Meu mau ...
Olivier Grégoire

@ OlivierGrégoire Sem problemas, e bem feito com sua resposta. :) Parece quase nostálgico olhar para essa resposta quando eu ainda estava adicionando os casos de teste e a saída à resposta, e respondi tudo no Java 7, porque ainda não entendia o Java 8. XD
Kevin Cruijssen 25/10

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}

Script de teste com menos golfe:

$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
}

Saída:

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, alternativo

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

Experimente online!

Têm intenção de ir a este nos últimos dias. Agora que finalmente tenho tempo para fazê-lo, já existe uma resposta mais curta do Python. Oh, bem, apenas postado como uma alternativa.

Entrada tomada como largura, livros


1

SOGL , 64 bytes

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

Explicação: Primeira função:

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

segunda função:

           →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 função espera um número (contagem de livros) na pilha e produz os livros das estantes

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

Um exemplo mais abaixo é e = 3 (largura da estante) eb = 8 (valor do livro)

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

esta é a linha superior / inferior da estante de livros e sempre fica na primeira parte da pilha (estante meio vazia)

Primeira 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

E a última 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

PHP> = 7.1, 138 bytes

for([,$w,$b]=$argv;$i<ceil($b/$w)*5;)echo str_pad("|".str_repeat(["","|X|"][$t=($i+1)%5>1],$i++<5&&$b%$w?$b%$w:$w),$w*3+1,"- "[$t])."|\n";

Versão Online


0

Tela , 33 bytes

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

Experimente aqui!

Explicação (alguns caracteres foram substituídos para parecer mais monoespaços):

|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'|

Assume a largura e a contagem de livros, respectivamente, como argumentos da linha de comando. Experimente online!

Explicação

Executamos um loop para imprimir as prateleiras uma a uma, de cima para baixo. A cada iteração, atualizamos b(o número de livros a serem impressos) subtraindo y(o número de livros impressos nessa iteração). Quando batinge 0, o loop sai.

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)

Como isso é um pouco envolvido, aqui está um exemplo da primeira iteração quando 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 depois imprime como

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

0

Pitão , 56 bytes

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

Aceita a largura da prateleira, a contagem de livros como argumentos separados nessa ordem. Experimente online aqui ou verifique todos os casos de teste de uma vez aqui .

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

Quarto (gforth) , 622 bytes (minimizado (remover comentários, recuo, nomes de palavras com 1 caractere) a 303 bytes)

Minha primeira peça com 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

Experimente online!

Saída

| ------------------ |
|| 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 ||
| ------------ |
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.