Вы должны сделать книгу!


15

Вы работаете на виртуальной старомодной печатной машине. Чтобы помочь вам быстрее оформить моноширинные буквы, вы решите создать самую короткую программу, которая поможет вам. Учитывая строку текста и размер страницы, генерировать и выводить каждую страницу текста.

Примеры

Например, с шириной страницы 14, высотой 7 и некоторым текстом, вот ваша книга:

14, 7, "Fruits make an extremely good snack due to their utterly scrumptious sweetness. They are also very healthy for you."
+------------+
| Fruits     |
| make an    |
| extremely  |
| good snack |
| due to     |
+------------+

+------------+
| their      |
| utterly    |
| scrumptio- |
| -us        |
| sweetness. |
+------------+

+------------+
| They are   |
| also very  |
| healthy    |
| for you.   |
|            |
+------------+

Вот основные настройки страницы:

|---i.e.14---|
+------------+ - 
| Xxxxxxxxxx | |
| Xxxxxxxxxx | i.  
| Xxxxxxxxxx | e. 
| Xxxxxxxxxx | 7
| Xxxxxxxxxx | | 
+------------+ - 

Несколько вещей

  1. Между краями страницы и текстом есть отступ в один пробел.
  2. Ширина и высота включают края коробки, если это не было ясно.
  3. Обтекание происходит только в том случае, если слово не помещается на одной строке.
  4. Программа должна иметь возможность выводить столько страниц, сколько необходимо, и только столько.
  5. Ваша программа должна поддерживать любой размер страницы, а не только 14 на 7.
  6. Это кодовый гольф, поэтому выигрывает самое маленькое решение в байтах (на любом языке).
  7. Не портите веселье. Стандартные лазейки явно не допускаются.

Да, и, кстати:

+------------+
| May the    |
| best book  |
| publisher  | 
| win. Good  |
| Luck!      |
+------------+

+------------+
| Best       |
| program    |
| so far:    | 
| Charcoal   |
|            |
+------------+

@rod Упс, исправлено.
я ..

7
Если вы имеете в виду, for example 14что этоe.g.
FrownyFrog


4
Нужно ли обрабатывать «многократные надрезы» для одного слова? (вроде scru-/-mpt-/-ious)
Арно

1
@Arnauld Если слово достаточно длинное, тогда да.
я ..

Ответы:


5

Python 2 , 306 304 283 279 байт

def f(w,h,s):
 b=[];w-=4;h-=2;H='+-'+'-'*w+'-+';x=l='';s=s.split()
 while s:
	W=s.pop(0)
	if W[w:]:W,s=W[:w-1]+'-',['-'+W[w-1:]]+s
	if len(l+W)<=w-(l>x):l+=' '*(l>x)+W
	else:b+=[l];l=W
 b+=[l]+[x]*h
 while any(b):print'\n'.join([H]+['| %-*s |'%(w,b.pop(0))for _ in' '*h]+[H,x,x])

Попробуйте онлайн!


Я думаю, что вы можете использовать, L=lenчтобы сохранить 2 байта всего ...
Час Браун

К вашему сведению (не уверен, что это нужно для адресации), тестовый пример, который я предложил ( 7, 3, "Three Is The Magic Number!"), дает ведущую пустую страницу.
Джонатан Аллан

1
@JonathanAllan Спасибо, исправил это :)
TFeld

3

Древесный уголь , 105 83 байта

NθNηM⁺η²↑F⪪S «W›Lι⁻θ⁴«⊞υ⁺…ι⁻θ⁵-≔⁺-✂ι⁻θ⁵Lι¹ι»⊞υι»Fυ«¿‹Lι±ⅈ «M⁻⁻⁴ⅈθ¹¿¬﹪ⅉ⊕η«↙↙Bθη↘→»»ι

Попробуйте онлайн! Ссылка является подробной версией коды deverbosifier не может обрабатывать и nilary операторов . Если бы допустимые пустые строки были приемлемы, я мог бы уменьшить их до 76 байт:

≔⁻N⁴θMθ→NηF⪪S «W›Lιθ«⊞υ⁺…ι⊖θ-≔⁺-✂ι⊖θLι¹ι»⊞υι»Fυ«¿‹⁺ⅈLιθ «F¬﹪ⅉ⊕η«⸿↙↙B⁺θ⁴η»⸿»ι

Объяснение:

NθNη

Введите ширину в qи высоту вh .

M⁺η²↑

Переместитесь в позицию, которая будет вызывать первый блок, который будет нарисован, но без создания верхнего поля.

F⪪S «

Зациклите все слова во входной строке.

W›Lι⁻θ⁴«

Повторите, пока слово слишком широкое, чтобы поместиться в поле.

⊞υ⁺…ι⁻θ⁵-

Выдвиньте как можно больше слова, которое подходит, и завершающий дефис.

≔⁺-✂ι⁻θ⁵Lι¹ι»

Приставьте дефис к остальной части слова.

⊞υι»

Нажмите остальную часть слова.

Fυ«

Обведите все слова, написанные через дефис.

¿‹Lι±ⅈ

Проверьте, подходит ли слово на текущей строке.

 «

Если так, то напечатайте пробел.

M⁻⁻⁴ⅈθ¹

В противном случае перейти к началу следующей строки.

¿¬﹪ⅉ⊕η

Проверьте, нужна ли нам новая коробка.

«↙↙Bθη↘→»»

Если так, то нарисуйте коробку.

ι

Наконец, напечатайте слово.




2

JavaScript (ES8), 242 байта

Спасибо @ Tvde1 за сообщение об ошибке

(s,w,h)=>s.split` `.map(g=s=>l=(l+s)[W=w-5]?s[l&&A(l),l='',w-4]?g('-'+s.slice(W),A(s.slice(0,W)+'-')):s:l?l+' '+s:s,n=o=l='',h-=2,b=`+${'-'.repeat(w-2)}+
`,A=s=>o+=(!n|n++%h?'':b+`
`+b)+`| ${s.padEnd(w-3)}|
`)&&(g=s=>A(s)&&n%h?g(''):b+o+b)(l)

Попробуйте онлайн!

комментарии

(s, w, h) =>                        // given s = string, w = width, h = height
  s.split` `                        // get all words by splitting the string on spaces
  .map(g = s =>                     // for each word s:
    l = (l + s)[W = w - 5] ?        //   if the word is too long for the current line:
      s[ l && A(l),                 //     append the line (if not empty)
         l = '',                    //     clear the line
         w - 4 ] ?                  //     if the word itself doesn't fit:
        g(                          //       do a recursive call with:
          '-' + s.slice(W),         //         a hyphen + the next part
          A(s.slice(0, W) + '-')    //         and append the current part + a hyphen
        )                           //       end of recursive call
      :                             //     else:
        s                           //       initialize a new line with this word
    :                               //   else:
      l ?                           //     if the current line is not empty:
        l + ' ' + s                 //       append a space + the word
      :                             //     else:
        s,                          //       initialize a new line with this word
    n = o = l = '',                 //   n = line counter, o = output, l = line
    h -= 2,                         //   adjust h
    b = `+${'-'.repeat(w - 2)}+\n`, //   b = border + linefeed
    A = s =>                        //   A = function that updates the output o:
      o += (                        //     append to o:
        !n | n++ % h ?              //       if we haven't reached an end of page:
          ''                        //         an empty string
        :                           //       else:
          b + `\n` + b              //         bottom border + linefeed + top border
      ) +                           //       followed by
      `| ${s.padEnd(w - 3)}|\n`     //       left border + padded text + right border
  ) &&                              // end of map()
  (g = s =>                         // g = recursive function taking s:
    A(s) &&                         //   append s
    n % h ?                         //   if we haven't reached an end of page:
      g('')                         //     go on with an empty line
    :                               //   else:
      b + o + b                     //     return top border + output + bottom border
  )(l)                              // initial call to g() with the last pending line

Попробуйте ваш пример текста с помощью 12и 7, некоторые строки / слова перевернуты.
Tvde1

1
@ Tvde1 Спасибо за сообщение об этом. Теперь это должно быть исправлено .
Арно

1

Желе , 93 байта

1,⁴Ṭị⁾+-W,`
ṣ⁶µḊṖs⁴_6¤j⁾--;@Ḣ;Ṫḟ0s⁴_©4¤µ€ẎŒṖK€€µL€>®ẸµÐḟṪ;€⁶x®¤ḣ€®s⁵_2¤Zz⁶x®¤j@€€⁾| ,U¤j@€¢ẎY

Полная программа, принимающая три аргумента (text , width, height) , который печатает страницу.

Попробуйте онлайн! NB. Слишком неэффективно, чтобы запустить пример из OP в пределах 60 секунд.

( 97 байт если пустая строка между страницами является обязательным требованием)

Как?

1,⁴Ṭị⁾+-W,` - Link 1, make header & footer: no arguments
  ⁴         - program's 2nd argument, width
1           - literal one
 ,          - pair = [1,width]
   Ṭ        - untruth = [1,0,0,...,0,0,1] (a 1 at index 1 and index width; 0 elsewhere)
     ⁾+-    - literal list of characters = "+-"
    ị       - index into (1-based & modular) = "+--...--+"
        W   - wrap = ["+---...--+']
          ` - use as both arguments of the dyad:
         ,  - pair = [["+---...--+'],["+---...--+']]

ṣ⁶µḊṖs⁴_6¤j⁾--;@Ḣ;Ṫḟ0s⁴_©4¤µ€ẎŒṖK€€µL€>®ẸµÐḟṪ;€⁶x®¤ḣ€®s⁵_2¤Zz⁶x®¤j@€€⁾| ,U¤j@€¢ẎY

 - Main link. This is long so splitting it up into parts like so:
ṣ⁶µ "A" µ€ "B" µ "C" µÐḟ "D"
ṣ⁶                           - split 1st argument (text) at spaces
  µ "A" µ€                   - for €ach resulting word do "A" (get hyphenated parts)
           "B"               - do "B" (all ways to partition those joining with spaces)
                     µÐḟ     - filter discard if:
               µ "C"         -   do "C" (any parts are too long)
                         "D" - do "D" (format the resulting list into the page-format)

"A" = ḊṖs⁴_6¤j⁾--;@Ḣ;Ṫḟ0s⁴_©4¤ - Hyphenate: list, word     e.g. "Something"
      Ḋ                        - dequeue                        "omething"
       Ṗ                       - pop                            "omethin"
            ¤                  - nilad followed by link(s) as a nilad
         ⁴                     -   program's 2nd argument  e.g. 9  (width)
           6                   -   literal six                  6
          _                    -   subtract                     3
        s                      - split into chunks             ["ome","thi","n"]
              ⁾--              - literal list of characters     "--"
             j                 - join                           "ome--thi--n"
                   Ḣ           - head (word)                    "S"
                 ;@            - concatenate (sw@p arguments)   "Some--thi--n"
                     Ṫ         - tail (word)                    "g"
                    ;          - concatenate                    "Some--thi--ng"
                      ḟ0       - filter out zeros (tail yields 0 for words of length 1)
                             ¤  - nilad followed by link(s) as a nilad:
                         ⁴      -   program's 2nd argument      9
                            4   -   literal four                4
                          _     -   subtract                    5
                           ©    -   copy to register & yield    5
                        s       - split into chunks             ["Some-","-thi-","-ng"]

"B" = ẎŒṖK€€ - Line arrangements: list of lists of hyphen-parts / single words
      Ẏ      - flatten by one (make a list of words and hyphen-parts
             - e.g. [["Not"],["hyph-","-ena-","-ted"]] -> ["Not","hyph-","-ena-","-ted"]
       ŒṖ    - partition e.g. [1,2,3]->[[[1],[2],[3]],[[1],[2,3]],[[1,2],[3]],[[1,2,3]]]
         K€€ - join with spaces for €ach for €ach e.g. ["one","two"]->"one two"

"C" = L€>®Ẹ - Any part too long?: one of the list of lines from "B"
      L€    - length of €ach
         ®  - recall from the register (width minus 4)
        >   - greater than (vectorises) - 1 if so 0 if not
          Ẹ - any truthy? (1 if any too long)

"D" = Ṫ;€⁶x®¤ḣ€®s⁵_2¤Zz⁶x®¤j@€€⁾| ,U¤j@€¢ẎY - Format as pages: list of valid arrangements
      Ṫ                                     - tail (last valid partition is greediest)
            ¤                               - nilad followed by links as a nilad:
         ⁶                                  -   literal space character
           ®                                -   recall from register (width minus 4)
          x                                 -   repeat elements
       ;€                                   - concatenate to €ach
               ®                            - recall from register (width minus 4)
             ḣ€                             - head €ach to index
                    ¤                       - nilad followed by links as a nilad:
                 ⁵                          -   program's 3rd argument, height
                   2                        -   literal two
                  _                         -   subtract
                     Z                      - transpose
                          ¤                 - nilad followed by link(s) as a nilad:

                       ⁶                    -   literal space character
                         ®                  -   recall from register (width minus 4)
                        x                   -   repeat elements

                      z                     - transpose with filler (repeated spaces)
                                    ¤       - nilad followed by link(s) as a nilad:
                               ⁾|<space>    -   literal list of characters = "| "
                                   U        -   upend = " |"
                                  ,         -   pair = ["| "," |"]
                           j@€€             - join for €ach for €ach (sw@p arguments)
                                        ¢   - call last link (1) as a nilad
                                     j@€    - join for €ach (sw@p arguments)
                                         Ẏ  - flatten by one
                                          Y - join with line feeds
                                            - implicit print

0

PHP, 299 байт

for($a=explode(" ",$argv[3]);$y|$e=strlen($d=$a[+$i++]);$x||print"|",$x|$e<$w?$e<$w-$x?$x+=$e+print" $d":$i-=!$x=!$y+=print str_pad("",$w-$x)." |
":$y+=print" ".substr($d,0,$w-2)."- |
".!$a[--$i]="-".substr($d,$w-2),$y>$argv[2]-2&&$y=!print"$t
")$y||$y=print$t=str_pad("+",2+$w=$argv[1]-3,"-")."+
";

Запустите php -nr '<code>' <width> <height> '<text>'или или попробуйте онлайн .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.