Musisz zrobić książkę!

15

Pracujesz w wirtualnej, staromodnej maszynie drukarskiej. Aby pomóc Ci szybciej rozmieszczać litery o stałej szerokości, decydujesz się na jak najkrótszy program, który może ci pomóc. Biorąc pod uwagę ciąg tekstu i rozmiar strony, wygeneruj i wydrukuj każdą stronę tekstu.

Przykłady

Na przykład, przy szerokości strony 14, wysokości 7 i pewnym tekście, oto twoja książka:

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

Oto podstawowe ustawienia strony:

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

Parę rzeczy

  1. Pomiędzy krawędziami strony a tekstem jest jeden margines.
  2. Szerokość i wysokość obejmują krawędzie pudełka, jeśli nie było to jasne.
  3. Owijanie występuje tylko wtedy, gdy słowo nie mieści się w jednej linii.
  4. Program musi być w stanie wydrukować tyle stron, ile potrzeba, i tylko tyle.
  5. Twój program musi obsługiwać dowolny rozmiar strony, nie tylko 14 na 7.
  6. To jest golf golfowy, więc wygrywa najmniejsze rozwiązanie w bajtach (w dowolnym języku).
  7. Nie rujnuj zabawy. Standardowe luki są oczywiście niedozwolone.

Aha, a przy okazji:

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

+------------+
| Best       |
| program    |
| so far:    | 
| Charcoal   |
|            |
+------------+
ja..
źródło
@rod Ups, naprawione.
i ..
7
Jeśli masz na myśli, for example 14że toe.g.
FrownyFrog,
Blisko związane.
Martin Ender
4
Czy musimy obsługiwać „wielokrotne cięcia” w jednym słowie? (jak scru-/-mpt-/-ious)
Arnauld
1
@Arnauld Jeśli słowo jest wystarczająco długie, to tak.
i ..

Odpowiedzi:

5

Python 2 , 306 304 283 279 bajtów

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

Wypróbuj online!

TFeld
źródło
Myślę, że można użyć L=lendo zapisania 2 bajtów łącznie ...
Chas Brown,
FYI (nie jestem pewien, czy wymaga adresowania), przypadek testowy, który zasugerowałem ( 7, 3, "Three Is The Magic Number!"), daje wiodącą pustą stronę.
Jonathan Allan
1
@JonathanAllan Dzięki, naprawiłem :)
TFeld,
3

Węgiel drzewny , 105 83 bajtów

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

Wypróbuj online! Łącze jest gadatliwy wersja kodu deverbosifier nie może obsłużyć i nilary operatorów . Jeśli wiodące puste wiersze byłyby dopuszczalne, mógłbym sprowadzić je do 76 bajtów:

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

Wyjaśnienie:

NθNη

Wprowadź szerokość do qi wysokość do h.

M⁺η²↑

Przejdź do pozycji, która uruchomi pierwsze pole do narysowania, ale bez generowania górnego marginesu.

F⪪S «

Zapętl wszystkie słowa w ciągu wejściowym.

W›Lι⁻θ⁴«

Powtarzaj, gdy słowo jest zbyt szerokie, aby zmieściło się w pudełku.

⊞υ⁺…ι⁻θ⁵-

Wciśnij tyle słowa, które będzie pasować, a łącznikiem.

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

Prefiks łącznika do reszty słowa.

⊞υι»

Naciśnij resztę słowa.

Fυ«

Pętla nad wszystkimi dzielonymi wyrazami.

¿‹Lι±ⅈ

Sprawdź, czy słowo pasuje do bieżącej linii.

 «

Jeśli tak, wydrukuj spację.

M⁻⁻⁴ⅈθ¹

W przeciwnym razie przejdź do początku następnego wiersza.

¿¬﹪ⅉ⊕η

Sprawdź, czy potrzebujemy nowego pudełka.

«↙↙Bθη↘→»»

Jeśli tak, narysuj pole.

ι

Na koniec wydrukuj słowo.

Neil
źródło
2

Perl 5 , 203 182 + 1 ( -a) = 183 bajtów

$t=($\=-3+shift@F)-2;$h=shift@F}{say$_='+'.'-'x$\.'-+';map{$_="";{$_.=shift@F;s/.{$t}\K..+/-/&&unshift@F,-$&;$_.=$";y///c+length$F[0]<$\&&redo}printf"| %-$\s|
",$_}3..$h;say;@F&&redo

Wypróbuj online!

Xcali
źródło
2

SOGL V0.12 , 92 bajty

Aē:b⁾\&?Q¶oQ}cI@*¼|a31žO■
.⁾:0EHC┌*¼+Q,θK;{⁴D@Κ+lc<‽Xd■Flc<‽ø;c⁾{Kh+;}D┌+■d┌Κ}}}■beb⁾%-⁾{ø■}

Wypróbuj tutaj!

dzaima
źródło
@JonathanAllan oh. : / naprawienie tego, aby umożliwić wielokrotne cięcia, prawdopodobnie będzie dużo bajtów ..
dzaima
2

JavaScript (ES8), 242 bajty

Dziękujemy @ Tvde1 za zgłoszenie błędu

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

Wypróbuj online!

Skomentował

(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
Arnauld
źródło
Wypróbuj przykładowy tekst za pomocą 12i 7, niektóre wiersze / słowa są odwrócone.
Tvde1
1
@ Tvde1 Dziękujemy za zgłoszenie tego. Teraz powinno to zostać naprawione .
Arnauld
1

Galaretka , 93 bajty

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

Pełen program, biorąc trzy argumenty ( text, width, height), który drukuje stron.

Wypróbuj online! NB Zbyt mało wydajny, aby uruchomić przykład z PO w granicach 60 sekund.

( 97 bajtów, jeśli pusta linia między stronami jest faktycznie wymaganiem)

W jaki sposób?

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
Jonathan Allan
źródło
0

PHP, 299 bajtów

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,"-")."+
";

Uruchom z php -nr '<code>' <width> <height> '<text>'lub lub wypróbuj online .

Tytus
źródło