Полиці ASCII


27

Ви знаєте ті полиці, що складаються, які в основному є дерев'яними ящиками, які можна складати разом? Ми будемо моделювати побудову деяких книжкових полиць із тих, хто має мистецтво ASCII.

Наші книги - це все зручно однакові за розміром і виглядають так:

|X|
|X|
|X|

Полиці для книг - це окремі скриньки, завжди три знаки зсередини (достатньо, щоб книга стояла вертикально), складена з |символів зліва та справа, -символи вгорі і внизу, і досить широкі, щоб вмістити Xкниги (де Xвхід ціле число). Наприклад, ось книжкова полиця розміром3 :

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

бо ти вмієш 3 книги в неї так

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

Вхід буде двома суворо позитивними цілими числами, Xі Yде Xширина полиць у нас (вимірюється в книгах), і Yскільки книг нам потрібно скласти. Якщо у нас більше книг, ніж вміщено на одній полиці, нам потрібно додати більше полиць у верхню частину. Наприклад, ось введення 4 wide / 6 books:

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

Якщо Y % X > 0, значить, кількість книг не є цілим числом, кратним розміру полиці, решта книг повинні знаходитись у верхньому лівому верхньому місці (як у випадку з 4 6вище), а решта частини цієї полиці заповнена пробіли.

Вхідні дані

  • Два суворо додатних цілих числа в будь-якому зручному форматі , кожне >0.
  • Ви можете взяти вхід у будь-якому порядку (наприклад, спочатку розмір полиць, потім кількість книг або навпаки). Будь ласка, вкажіть у своєму поданні порядок введення.
  • Ви можете з упевненістю припустити, що жоден вхід не буде більшим за [int]розміром (або еквівалентом) вашої мови .

Вихідні дані

У результаті ASCII художнє представлення книг і книжкових полиць.

Правила

  • Провідні чи кінцеві рядки чи пробіли - це необов’язково, до тих пір, поки самі символи правильно вишикуються.
  • Прийнятна або повна програма, або функція. Якщо функція, ви можете повернути вихід, а не надрукувати його.
  • Якщо можливо, додайте посилання на онлайн-тестувальне середовище, щоб інші люди могли спробувати ваш код!
  • Стандартні лазівки заборонені.
  • Це тому діють усі звичайні правила гольфу, і найкоротший код (у байтах) виграє.

Подальші приклади

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

Чи можу я зробити так, щоб полиця з найменшою кількістю книг була на дні, так, як вона заповнюється зверху вниз
Золоте співвідношення

1
@GoldenRatio Ні, книги повинні бути заповнені знизу вгору, зліва направо.
AdmBorkBork

Відповіді:


14

JavaScript (ES6), 100 99 98 байт

Приймає ширину wта кількість книг bу синтаксисі каррі (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

Відформатовано та прокоментовано

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

Тестові справи


9

Bash (+ утиліти), 130, 108, 106 байт

Єдиний, безперервний трубопровід, який надає ваші книжкові полиці.

Журнал змін:

  • Трохи оптимізований вираз sed, -12 байт (Thx @Riley!)
  • Замінено printf + seqна сирий printf, -10 байт
  • Відновив другий вираз sed, -2 байти

Гольф

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

Спробуйте в Інтернеті!

Як це працює

$./shelf 2 3

printf %$2s\\n- генерувати n символів пробілу, по одному на книгу (показано як _)

___

fold -$1 - складіть їх по довжині полиці

__
_

sed "s/ /|X|/g;"- замінити _з X, додайте книжкові обкладинки

|X||X|
|X|

:;/.\{$[$1*3]\}/!s/$/ /;t- правий майданчик з пробілами (показано як _)

|X||X|
|X|___

h;s/./-/gp;x;p;p;p;x- потрій кожний рядок і додай ---до і після нього.

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

sed 's/.*/|&|/'|tac- обернути лінії | |, зворотно з tac

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

У першому sed можна використовувати безіменну етикетку, а tзамість bцього вам не потрібна {}. Ви можете пропустити те, s/./-/gщо вони вже є -. Спробуйте в Інтернеті!
Райлі

@Riley Це чудова порада, дякую!
зеппелін

6

Python 2, 133 113 105 байт

Я впевнений, що є кращий спосіб ...

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

Вхід береться width, books

-20 байт завдяки @ovs за те, що помітили непотрібну лямбда-функцію!
-8 байт завдяки @ovs за скорочення вводу.


X,Y=input()це коротший спосіб прийняти значення.
ов

@ovs О, зачекайте, я поставив це для моєї першої спроби. Уопс. Приємний улов, дякую!
HyperNeutrino

1
@ovs Спасибі, тож тоді введення приймається як X, Y, правда?
HyperNeutrino

2
Я думаю, що ви можете зберегти два байти, визначившись '|'як змінну.
Ørjan Johansen

6

Пакетна, 261 байт

@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

Використовую мій трюк з моєї відповіді на партію Давайте пограємо в теніс, щоб легко надрукувати багато |символів.


5

Haskell , 100 байт

x#yповертає рядок для ширини xта yкниги.

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

Спробуйте в Інтернеті!

Основна функція / оператор - це #. Коли x<yвін розбиває книги на, y-xа xпотім повторюється. Коли x>=y, wіb є два типи лінії, мінус зовнішні |s і символ нового рядка.

Оператор-помічник s?nоб'єднує nкопії рядка s.


5

PowerShell , 149 134 байт

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

Спробуйте в Інтернеті!

Займає вхідний $width і ooks $b. Встановлює рядок $sяк одну з горизонтальних полиць. Тоді у нас є дваif заяви.

Перший перевіряє, чи є у нас «залишки» книг. Якщо так, ми виводимо полицю, (кількість книг плюс кількість пробілів)*3 та іншу полицю.

Далі ми бачимо, чи залишилися у нас книги після видалення залишків ( $a). Таке ж налаштування, за винятком того, що ми використовуємо $wкількість книг. Оскільки в цей момент $bгарантовано буде кратним $w(оскільки ми видалили решту,$a ), нам не потрібно турбуватися про округлення.

Видалено [math]::Floor()Виклик , заощадивши 15 байт

Усі ці рядки залишаються на конвеєрі, і неявне Write-Outputвідбувається при завершенні програми.


4

CJam , 62 61 байт

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

Вводиться як " width books

Спробуйте в Інтернеті!

Пояснення

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

Пітон 3, 142 байти

Ще над цим працюю. b- для "кількості книг" і wдля ширини полиць.

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

Ласкаво просимо до PPCG! Це не працює для мене, якщо не R=b%wбуде перенесено вниз до наступного рядка. Крім того, ви повинні мати можливість видалити пробіл навколо цих трьох, =щоб зберегти кілька байт.
Ділова кішка

Ласкаво просимо до PPCG!
AdmBorkBork

Ви можете замінити d+3*p+d if R!=0 else ''наR and d+3*p+d or''
shooqie

@shooqie Мені цікаво, як це можна було оцінити до результату d+3*p+d?
Хуан Мелейро

1
Ви можете зберегти кілька байтів, поставивши всі визначення в один рядок, використовуючи крапки з комою.
L3viathan

3

AHK, 208 байт

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%

Є кілька речей, які мене дратують від гольфу далі:

  • AutoHotkey не має вбудованої функції повтору
  • Ви не можете безпосередньо використовувати передані аргументи (%1% & %2%) в математичних функціях, тому що ті очікують введення змінної чи числа, і це вважатиме, що нерозміщений 1буде номером один, а не ім'ям змінної
  • Я не дуже хороший у гольфі

Простіша для читання версія вищезгаданого виглядає так:

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%

Якщо Loopдужка не використовує дужки {}, то лише наступний рядок є частиною циклу. Якщо встановити значення змінної, використовуючи :=замість =, ви можете скинути символи втечі знаку відсотка. Tilde n - символ нового рядка.


3

Java 7, 230 224 222 байти

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

Пояснення:

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

Код тесту:

Спробуйте тут.

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

Вихід:

|------------------|
||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 Зважаючи на те, що я розміщував це близько 1,5 року тому, я не здивований, що в ньому можна грати в гольф досить істотно. ;)
Кевін Круїссен

Ой ... Я не перевіряв дату: я бачив лише, що це питання активне і що можливий повний інший алгоритм для Java. Мій поганий ...
Олів'є Грегоар

@ OlivierGrégoire Немає проблем, і добре зробила свою відповідь. :) Це майже ностальгічне враження від цієї відповіді, коли я ще додавав тестові випадки та виводив відповідь і відповідав на все в Java 7, тому що я ще не зрозумів Java 8. XD
Kevin Cruijssen

2

PowerShell, 109 байт

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

Менш тестовий сценарій для гольфу:

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

Вихід:

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 байт, альтернатива

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 байт

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

Спробуйте в Інтернеті!

Останні кілька днів мали сенс зайнятися цим. Тепер, коли я нарешті встиг це зробити, вже є коротша відповідь Python. Ну добре, щойно розміщена як альтернатива.

Введення, прийняте як ширина, книги


1

SOGL , 64 байти

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

Пояснення: Перша функція:

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

друга функція:

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

ця функція очікує на стек число (кількість книг) і виводить книжкові полиці книг

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

Далі наведений приклад - e = 3 (ширина книжкової полиці) і b = 8 (кількість книги)

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

це верхній / нижній рядок книжкової полиці і завжди залишається на першій частині стека (напівпорожня полиця)

Перша основна частина

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

І остання частина

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

Полотно , 33 байти

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

Спробуйте тут!

Пояснення (деякі символи були замінені, щоб мати вигляд більш простору):

|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

Піп -n , 45 байт

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

Вважає ширину та кількість книг відповідно аргументами командного рядка. Спробуйте в Інтернеті!

Пояснення

Запускаємо цикл, щоб надрукувати полки по черзі зверху вниз. Під час кожної ітерації ми оновлюємо b(кількість книг для друку) відніманням y(кількість книг, надрукованих на цій ітерації). Коли bдосягає 0, цикл виходить.

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)

Оскільки це мало пов'язано, ось приклад першої ітерації, коли 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|   |"];"|---------|"]

який потім друкується як

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

0

Pyth , 56 байт

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

Приймає ширину полиці, кількість книг є окремими аргументами в тому порядку. Спробуйте в Інтернеті тут або перевірити всі тестові випадки тут .

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

Далі (gforth) , 622 байти (мінімізовано (видалити коментарі, відступи, назви 1-знакових слів) до 303 байт)

Моя перша гра з 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

Спробуйте в Інтернеті!

Вихідні дані

| ------------------ |
|| 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 ||
| ------------ |
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.