Étagères ASCII

27

Vous connaissez ces étagères empilables qui sont essentiellement des boîtes en bois qui peuvent être empilées ensemble? Nous allons simuler la construction de certaines étagères à partir de celles avec de l'art ASCII.

Nos livres sont tous de taille pratique et uniforme et ressemblent tous à ce qui suit:

|X|
|X|
|X|

Les étagères sont des boîtes individuelles, toujours trois caractères de haut à l'intérieur (assez pour tenir un livre debout), composées de |caractères à gauche et à droite, des -caractères pour le haut et le bas, et assez larges pour contenir des Xlivres (où Xest une entrée entier). Par exemple, voici une étagère de taille 3:

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

parce que vous pouvez y insérer des 3livres comme ça

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

L'entrée va être deux entiers strictement positifs Xet Y, où Xest la largeur des étagères que nous avons (mesurée en livres), et Ycombien de livres nous devons empiler. Si nous avons plus de livres qu'il n'y en a sur une seule étagère, nous devons ajouter plus d'étagères en haut. Par exemple, voici une entrée 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, ce qui signifie que le nombre de livres n'est pas un multiple entier de la taille de l'étagère, les livres restants doivent se placer en haut à gauche (comme dans le cas 4 6ci-dessus) et la partie restante de cette étagère remplie de les espaces.

Contribution

  • Deux entiers strictement positifs dans n'importe quel format pratique , chacun >0.
  • Vous pouvez prendre l'entrée dans l'un ou l'autre ordre (par exemple, la taille des étagères en premier, puis le nombre de livres, ou vice versa). Veuillez indiquer dans votre soumission l'ordre de saisie.
  • Vous pouvez sans risque supposer qu'aucune entrée ne sera plus grande que la [int]taille par défaut de votre langue (ou l'équivalent).

Sortie

La représentation artistique ASCII résultante des livres et des étagères.

Règles

  • Les sauts de ligne ou les espaces de début ou de fin sont tous facultatifs, tant que les caractères eux-mêmes s'alignent correctement.
  • Un programme complet ou une fonction sont acceptables. S'il s'agit d'une fonction, vous pouvez renvoyer la sortie plutôt que de l'imprimer.
  • Si possible, veuillez inclure un lien vers un environnement de test en ligne afin que d'autres personnes puissent essayer votre code!
  • Les failles standard sont interdites.
  • Il s'agit de donc toutes les règles de golf habituelles s'appliquent et le code le plus court (en octets) l'emporte.

D'autres exemples

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||
|------------|
AdmBorkBork
la source
Puis-je faire en sorte que l'étagère avec le moins de livres soit en bas, donc comme si elle remplissait de haut en bas
Golden Ratio
1
@GoldenRatio Non, les livres doivent être remplis de bas en haut, de gauche à droite.
AdmBorkBork

Réponses:

14

JavaScript (ES6), 100 99 98 octets

Prend la largeur wet le nombre de livres bdans la syntaxe 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

Formaté et commenté

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

Cas de test

Arnauld
la source
9

Bash (+ utilitaires), 130, 108, 106 octets

Un pipeline shell unique et continu pour rendre vos étagères.

Journal des modifications:

  • Optimisation de la première expression sed un peu, -12 octets (Thx @Riley!)
  • Remplacé printf + seqpar un brut printf, -10 octets
  • Refactorisé la deuxième expression sed, -2 octets

Golfé

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

Essayez-le en ligne!

Comment ça marche

$./shelf 2 3

printf %$2s\\n- générer n espaces blancs, un par livre (montré comme _)

___

fold -$1 - pliez-les par la longueur de l'étagère

__
_

sed "s/ /|X|/g;"- remplacer _par X, ajouter des couvertures de livres

|X||X|
|X|

:;/.\{$[$1*3]\}/!s/$/ /;t- pad droit avec espaces (montré comme _)

|X||X|
|X|___

h;s/./-/gp;x;p;p;p;x- tripliquez chaque ligne et ajoutez-la ---avant et après.

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

sed 's/.*/|&|/'|tac- envelopper les lignes | |, inverser avec tac

|------|
||X|   |
||X|   |
||X|   |
|------|
|------|
||X||X||
||X||X||
||X||X||
|------|
Zeppelin
la source
Dans le premier sed, vous pouvez utiliser une étiquette sans nom, et tau lieu de bcela, vous n'avez pas besoin de {}. Vous pouvez ignorer le s/./-/gcar ils sont déjà -s. Essayez-le en ligne!
Riley
@Riley C'est un excellent conseil, merci!
zeppelin
6

Python 2, 133 113 113 105 octets

Je suis sûr qu'il y a une meilleure façon ...

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

L'entrée est prise width, books

-20 octets grâce à @ovs pour avoir remarqué une fonction lambda inutile!
-8 octets grâce à @ovs pour avoir raccourci l'entrée.

HyperNeutrino
la source
X,Y=input()est un moyen plus court de prendre les valeurs to.
ovs
@ovs Oh attendez, je mets ça là pour mon premier essai. Oups. Belle prise, merci!
HyperNeutrino
1
@ovs Merci, alors la saisie est considérée comme X, Y, non?
HyperNeutrino
2
Je pense que vous pouvez enregistrer deux octets en définissant '|'comme une variable.
Ørjan Johansen
6

Lot, 261 octets

@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

Utilise mon astuce de ma réponse Lot à Jouons au tennis pour imprimer facilement beaucoup de |personnages.

Neil
la source
5

Haskell , 100 octets

x#yrenvoie la chaîne de largeur xet de ylivres.

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

Essayez-le en ligne!

La fonction / opérateur principal est #. Quand x<yil divise les livres en y-xet x, puis revient. Lorsque x>=y, wet bsont les deux types de lignes, moins les extérieurs |s et la nouvelle ligne.

L'opérateur d'assistance s?nconcatène des ncopies de la chaîne s.

Ørjan Johansen
la source
5

PowerShell , 149 134 octets

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

Essayez-le en ligne!

Prend $width d' entrée et $books. Définit la chaîne $scomme l'une des étagères horizontales. Ensuite, nous avons deux ifdéclarations.

Le premier vérifie si nous avons des livres "restants". Si c'est le cas, nous sortons l'étagère, le (nombre de livres plus le nombre d'espaces) *3et une autre étagère.

Ensuite, nous voyons s'il nous reste des livres après avoir supprimé les restes ( $a). Même configuration, sauf que nous utilisons un $wcertain nombre de livres. Puisqu'à ce stade, il $best garanti d'être un multiple de $w(parce que nous avons supprimé le reste, $a), nous n'avons pas à nous soucier de l'arrondi.

Suppression de l' [math]::Floor()appel, économisant 15 octets

Toutes ces chaînes sont laissées sur le pipeline et Write-Outputse produisent implicitement à la fin du programme.

AdmBorkBork
la source
4

CJam , 62 61 octets

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

Prend l'entrée comme width books

Essayez-le en ligne!

Explication

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
Chat d'affaires
la source
4

Python 3, 142 octets

Travaille toujours dessus. bcorrespond au «nombre de livres» et wà la largeur de l'étagère.

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))
Juan Meleiro
la source
Bienvenue chez PPCG! Cela ne fonctionne pas pour moi à moins qu'il ne R=b%wsoit déplacé vers la ligne suivante. En outre, vous devriez pouvoir supprimer les espaces autour de ces trois =pour économiser quelques octets.
Business Cat
Bienvenue chez PPCG!
AdmBorkBork
Vous pouvez remplacer d+3*p+d if R!=0 else ''parR and d+3*p+d or''
shooqie
@shooqie Je suis curieux, comment cela pourrait-il évaluer le résultat d+3*p+d?
Juan Meleiro
1
Vous pouvez enregistrer quelques octets en mettant toutes les définitions sur une seule ligne à l'aide de points-virgules.
L3viathan
3

AHK, 208 octets

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%

Il y a quelques choses qui me frustrent de continuer à jouer au golf:

  • AutoHotkey n'a pas de fonction de répétition intégrée
  • Vous ne pouvez pas utiliser directement les arguments passés ( %1%& %2%) dans les fonctions mathématiques car ceux-ci attendent une entrée de variable ou de nombre et il supposera que le caractère non échappé 1est le numéro un plutôt que le nom de la variable
  • Je ne suis pas très bon au golf

Une version plus facile à lire de ce qui précède ressemble à ceci:

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 Loopn'utilise pas de crochets {}, alors seule la ligne suivante fait partie de la boucle. Si vous définissez la valeur d'une variable à l'aide de :=au lieu de =, vous pouvez supprimer les caractères d'échappement du signe pourcentage. Tilde n est le caractère de nouvelle ligne.

Ingénieur Toast
la source
3

Java 7, 230 224 222 octets

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

Explication:

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

Code de test:

Essayez-le ici.

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

Sortie:

|------------------|
||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||
|------------|
Kevin Cruijssen
la source
1
Je ne sais pas comment, mais ça ressemble à des lambdas et .repeatvraiment, vraiment aider dans ce défi .
Olivier Grégoire
@ OlivierGrégoire Étant donné que j'ai posté cela il y a environ 1,5 an, je ne suis pas surpris qu'il puisse être joué assez substantiellement. ;)
Kevin Cruijssen
Ow ... Je n'avais pas vérifié la date: j'ai seulement vu que cette question était active et qu'un autre algorithme complet pour Java était possible. Mon mauvais ...
Olivier Grégoire
@ OlivierGrégoire Pas de problème et bravo pour votre réponse. :) Il me semble presque nostalgique de revenir sur cette réponse lorsque j'ajoutais encore les cas de test et la sortie à la réponse, et que je répondais à tout dans Java 7, parce que je ne comprenais pas encore Java 8. XD
Kevin Cruijssen
2

PowerShell, 109 octets

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 test moins 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
}

Sortie:

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 octets, alternative

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

Python 2 , 120 118 octets

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

Essayez-le en ligne!

Je voulais essayer celui-ci depuis quelques jours. Maintenant que j'ai enfin le temps de le faire, il y a déjà une réponse Python plus courte. Eh bien, vient d'être publié comme alternative.

Entrée prise comme largeur, livres

ElPedro
la source
1

SOGL , 64 octets

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

Explication: Première fonction:

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

deuxième fonction:

           →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|"]]

cette fonction attend un nombre (nombre de livres) sur la pile et affiche les livres des étagères

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

Un exemple plus bas donné est e = 3 (largeur de la bibliothèque) et b = 8 (montant du livre)

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

c'est la ligne supérieure / inférieure de la bibliothèque et reste toujours sur la première partie de la pile (bibliothèque à moitié vide)

Première partie principale

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

Et la dernière partie

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
dzaima
la source
1

Java (JDK) , 124 octets

s->b->{for(int i=0;i++<(b-~s)/s*5;)System.out.printf("|%-"+s*3+"s|%n",i%5<2?"-".repeat(s*3):"|X|".repeat(i<5&b%s>0?b%s:s));}

Essayez-le en ligne!

Crédits

Olivier Grégoire
la source
0

PHP> = 7.1, 138 octets

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

Version en ligne

Jörg Hülsermann
la source
0

Toile , 33 octets

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

Essayez-le ici!

Explication (certains caractères ont été remplacés pour paraître plus monospaces):

|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
dzaima
la source
0

Pip -n , 45 octets

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

Prend la largeur et le nombre de livres, respectivement, comme arguments de ligne de commande. Essayez-le en ligne!

Explication

Nous exécutons une boucle pour imprimer les étagères une par une de haut en bas. À chaque itération, nous mettons à jour b(le nombre de livres à imprimer) en soustrayant y(le nombre de livres imprimés sur cette itération). Quand batteint 0, la boucle se termine.

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)

Parce que c'est un peu impliqué, voici un exemple de la première itération lorsque 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|   |"];"|---------|"]

qui imprime ensuite

|---------|
||X||X|   |
||X||X|   |
||X||X|   |
|---------|
DLosc
la source
0

Pyth , 56 octets

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

Accepte la largeur d'étagère, le nombre de livres comme arguments séparés dans cet ordre. Essayez-le en ligne ici ou vérifiez tous les cas de test en même temps ici .

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
Sok
la source
0

Forth (gforth) , 622 octets (minimisé (supprimer les commentaires, l'indentation, les noms de mots de 1 caractère) à 303 octets)

Ma première pièce avec 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

Essayez-le en ligne!

Sortie

| ------------------ |
|| 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 ||
| ------------ |
pmg
la source