24
\$\begingroup\$

(Note: This is my first ever code golf question, but as far as I can tell, nobody else has done exactly this, so I should be good.)

Your task is to make a program or function that takes in a string s and an integer n, and returns or outputs that text wrapped into multiple lines. Each word must be wholly on a line; i.e. no words split in the middle. Each line can be no longer than n characters long, and you must fit as many words as possible on each line.

Example:

s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat." 
n = 50

output:
Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Sed eget erat lectus. Morbi mi mi, fringilla
sed suscipit ullamcorper, tristique at mauris.
Morbi non commodo nibh. Pellentesque habitant
morbi tristique senectus et netus et malesuada
fames ac turpis egestas. Sed at iaculis mauris.
Praesent a sem augue. Nulla lectus sapien, auctor
nec pharetra eu, tincidunt ac diam. Sed ligula
arcu, aliquam quis velit aliquam, dictum varius
erat.

Your output can be an array of strings or a single string with line breaks. Also, you can assume no words will be longer than n, so don't worry about dealing with weird cases.

Standard I/O rules apply, and standard loopholes are prohibited. Trailing spaces are allowed.

Since this is , the shortes solution in bytes wins.

Here is an example program in Python that would work.

\$\endgroup\$
14
  • \$\begingroup\$ Format a list of words \$\endgroup\$
    – DELETE_ME
    Dec 1, 2018 at 1:49
  • 3
    \$\begingroup\$ n is the max line length ? or the length we have to reach before line break ? \$\endgroup\$
    – david
    Dec 1, 2018 at 10:27
  • 1
    \$\begingroup\$ @david, or the number of lines? \$\endgroup\$ Dec 1, 2018 at 13:24
  • 1
    \$\begingroup\$ 28 bytes Python is it relevant? \$\endgroup\$
    – david
    Dec 1, 2018 at 14:12
  • 3
    \$\begingroup\$ n is the max line length, sorry that that was not clear. I will clarify. Also, the rules have now been updated so a simple split doesn't work. \$\endgroup\$
    – ATMunn
    Dec 1, 2018 at 16:09

28 Answers 28

7
\$\begingroup\$

Python 2, 26 bytes

from textwrap import*
fill

Try it online!

Meh... built-ins are boring... instead, have a nice 87-byte solution here:

s,n=input()
x=''
for i in s.split():c=n<len(x+i);exec'print x'*c;x=x*-~-c+i+' '
print x

Try it online!

Outputs trailing spaces.

\$\endgroup\$
5
\$\begingroup\$

PHP, 8 bytes

Admittedly not the most original solution, but PHP has a native function that matches your requirements perfectly!

wordwrap:

string wordwrap ( string $str [, int $width = 75 [, string $break = "\n" [, bool $cut = FALSE ]]] )

Wraps a string to a given number of characters using a string break character.

Use like so:

$str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat.";
echo wordwrap($str, 50);

Or Try it online!

\$\endgroup\$
0
5
\$\begingroup\$

JavaScript (ES6),  75 73  72 bytes

Takes input as (string)(n).

s=>n=>s.split` `.map(w=>r=(u=r?r+' '+w:w)[n]?(o+=r+`
`,w):u,o=r='')&&o+r

Try it online!

Variables

The formatted output is stored in \$o\$ (in green below).

The updated line \$u\$ is defined as the concatenation of:

  • the current line \$r\$ (in black below)
  • a space if \$r\$ is not empty, or nothing otherwise (in orange below)
  • the new word \$w\$ (in blue below)

We need to insert a line break whenever the \$n\$-th character of \$u\$ is set (0-indexed, in red below).

Example

\$n=16\$ and \$s\$ = "LOREM IPSUM DOLOR"

Adding "LOREM": $$\small\begin{array}{|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|} \hline 00&01&02&03&04&05&06&07&08&09&10&11&12&13&14&15&\color{red}{16}\\ \hline \color{blue}L&\color{blue}O&\color{blue}R&\color{blue}E&\color{blue}M&&&&&&&&&&&&\\ \hline\end{array} $$

Adding "IPSUM": $$\small\begin{array}{|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|} \hline 00&01&02&03&04&05&06&07&08&09&10&11&12&13&14&15&\color{red}{16}\\ \hline L&O&R&E&M&\color{orange}\bullet&\color{blue}I&\color{blue}P&\color{blue}S&\color{blue}U&\color{blue}M&&&&&&\\ \hline\end{array} $$

Adding "DOLOR": $$\small\begin{array}{|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|} \hline 00&01&02&03&04&05&06&07&08&09&10&11&12&13&14&15&\color{red}{16}\\ \hline L&O&R&E&M&\bullet&I&P&S&U&M&\color{orange}\bullet&\color{blue}D&\color{blue}O&\color{blue}L&\color{blue}O&\color{blue}R\\ \hline\end{array} $$

$$\small\begin{array}{|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|} \hline 00&01&02&03&04&05&06&07&08&09&10&11&12&13&14&15&\color{red}{16}\\ \hline \color{green}L&\color{green}O&\color{green}R&\color{green}E&\color{green}M&\color{green}\bullet&\color{green}I&\color{green}P&\color{green}S&\color{green}U&\color{green}M&\color{green}\hookleftarrow&&&&&\\ \hline D&O&L&O&R&&&&&&&&&&&&\\ \hline\end{array} $$

\$\endgroup\$
1
  • \$\begingroup\$ Trailing spaces are allowed. maybe r+w+' '? \$\endgroup\$
    – l4m2
    Dec 3, 2018 at 0:24
5
\$\begingroup\$

Perl 6, 46 29 bytes

{;*.comb(/.**{1..$_}[\s|$]/)}

Try it online!

Regex based solution that takes input curried, like f(n)(s) and returns a list of lines. Each line except the last has a trailing whitespace

Explanation:

{;*                         }   # Anonymous code block that returns a Whatever lambda
   .comb(/                /)    # Split the string by
          .**{1..$_}            # Up to n characters
                    [\s|$]      # Terminated by a whitespace char or the end of the string
\$\endgroup\$
4
\$\begingroup\$

Vim, 15 bytes/keystrokes

DJ:se tw=<C-r>"
gq_

A text formatting question? I know just the tool for the job! And it even has my name in the first two keystrokes :D

<C-r> means ctrl-r.

This could ever so slightly shorter in V, but I prefer answering in vanilla vim for answers that really show off how concise vim can be for the right challenge. And the difference is so small anyway.

This could also be the following for 15 bytes as well:

:se tw=<C-r><C-w>
ddgq_

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Explanation: DJ:: This program has been made by DJ, our favorite cat with a diamond around his neck. [...] \$\endgroup\$ Dec 1, 2018 at 19:10
4
\$\begingroup\$

R, 36 27 bytes

R has this as a built-in (strwrap), we return a vector of split lines.

function(s,n)strwrap(s,n+1)

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Yes, that should be allowed. Arrays of lines are allowed, so I don't see why this would be any different. \$\endgroup\$
    – ATMunn
    Dec 1, 2018 at 16:14
4
\$\begingroup\$

Haskell, 70 bytes

s!n|length s<=n=[s]|(t,_:d)<-splitAt(until((<'!').(s!!))pred n)s=t:d!n
\$\endgroup\$
0
3
\$\begingroup\$

Python 2, 74 bytes

s,n=input()
while s:i=n;exec"i-=' '<(s+' '*n)[i];"*n;print s[:i];s=s[i+1:]

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Java (JDK), 46 44 bytes

Basically a pure regex solution in Java, almost certainly the shortest I've written.

Cheers to Kevin for helping to cut down the bytes in the regex even further!

n->s->s.replaceAll(".{1,"+n+"}( |$)","$0\n")

Try it online!

Using a curried lamdba, it creates a regex to greedily match up to n characters followed by either a space or end of string. It then replaces those characters with themselves followed by a newline.

\$\endgroup\$
6
  • \$\begingroup\$ @KevinCruijssen [ $] actually just matches a space or $ if I remember correctly, rather than the end of string. It does seem to work though, so it looks like it can just be golfed down to a single space for even fewer bytes. \$\endgroup\$ Dec 5, 2018 at 10:36
  • \$\begingroup\$ Ah, it can indeed be just a space, since you add newlines and don't need to add an additional trailing newline at the end. \$\endgroup\$ Dec 5, 2018 at 10:38
  • 1
    \$\begingroup\$ You can golf 2 more bytes removing the parenthesis in the regex, and use $0 instead of $1. \$\endgroup\$ Dec 5, 2018 at 10:44
  • \$\begingroup\$ @KevinCruijssen Nice one! It's just a shame that replaceAll is so verbose! \$\endgroup\$ Dec 5, 2018 at 10:53
  • 2
    \$\begingroup\$ For me it is wrong, appear if I modify the Latin phrase of the exercise in the way it end with"...dictum varius a b c erat." There is a unnecessary new line after c letter... \$\endgroup\$
    – user58988
    Dec 5, 2018 at 17:00
2
\$\begingroup\$

Mathematica, 16 bytes

InsertLinebreaks

Built-in function. Takes a string and an integer as input and returns a string as output.

InsertLinebreaks["string", n]
 inserts newline characters to make no line longer than n characters.

\$\endgroup\$
2
\$\begingroup\$

Powershell, 40 83 bytes

Test case with n=80 added.

param($s,$n)$s-split' '|%{if(($o+$_|% le*)-lt$n){$o+=' '*!!$o+$_}else{$o;$o=$_}}
$o

Test script:

$f = {

param($s,$n)$s-split' '|%{if(($o+$_|% le*)-lt$n){$o+=' '*!!$o+$_}else{$o;$o=$_}}
$o

}

@(
,(50, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat.",
"Lorem ipsum dolor sit amet, consectetur adipiscing",
"elit. Sed eget erat lectus. Morbi mi mi, fringilla",
"sed suscipit ullamcorper, tristique at mauris.",
"Morbi non commodo nibh. Pellentesque habitant",
"morbi tristique senectus et netus et malesuada",
"fames ac turpis egestas. Sed at iaculis mauris.",
"Praesent a sem augue. Nulla lectus sapien, auctor",
"nec pharetra eu, tincidunt ac diam. Sed ligula",
"arcu, aliquam quis velit aliquam, dictum varius",
"erat.")
,(80, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat.",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus.",
"Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non",
"commodo nibh. Pellentesque habitant morbi tristique senectus et netus et",
"malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue.",
"Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu,",
"aliquam quis velit aliquam, dictum varius erat.")
) | %{
    $n,$s,$expected = $_
    $result = &$f $s $n
    "$result"-eq"$expected"
    # $result   # uncomment this line to dispaly a result
}

Output:

True
True
\$\endgroup\$
2
2
\$\begingroup\$

C (gcc), 68 bytes

i;b(s,n,l)char*s,*l;{for(i=n;*++s;i--||(i=l-s+n,*l=10))l=*s-32?l:s;}

Try it online!

Thanks to ceilingcat, save 2 bytes by moving global char*l to parameter.

\$\endgroup\$
0
2
\$\begingroup\$

APL (Dyalog Unicode), 14 bytesSBCS

Infix function; left argument is n, right argument is n.

⎕CY'dfns'⋄wrap

Try it online!

⎕CYcopy in the dfns library

 then

wrap[c] use the wrap[n] function

[c] code of that function
[n] notes for that function


Golfed version of wrap, 59 bytesSBCS

{⍺≥≢⍵:⍵⋄(t↑⍵),2↓⎕TC,⍺∇⍵↓⍨t+b⊃⍨t←⊃⌽⍺,g/⍨⍺≥g←⍸(⍺+1)↑b←' '=⍵}

Try it online!

{} dfn; is left argument (width), is right argument (string)

≢⍵ tally (number of characters) of string

⍺≥: if width is greater than or equal to that, then:

   return the string

 otherwise:

  ' '=⍵ Boolean mask where blanks are equal to the string

  b← store in b (for blanks)

  ()↑ take the following number of elements from that:

   ⍺+1 one more than the width

  indices where true

  g← store in g (for gaps)

  ⍺≥ Boolean mask where the width is greater than or equal to that

  g/⍨ filter the gap indices by that

  ⍺, append that to the width

  ⊃⌽ pick the last element of that (lit. pick the first of the reversed)

  t← store in t (for take)

  b⊃⍨ use that to pick an element from the mask of blanks

  t+ add that to t

  ⍵↓⍨ drop that many characters from the string

  ⍺∇ recurse on that with the same left left argument

  ⎕TC, append that to the list of terminal control characters (8:HT, 10:NL, 13:CR)

  2↓ drop the first two character from that (leaving just a leading 13:CR)

  (), append that to the following:

   t↑⍵ the first t characters of the string

\$\endgroup\$
2
\$\begingroup\$

Japt, 20 bytes

¸rÈ+Yi[X·ÌY]¸Ê>V?R:S

Try it online!

Thanks to Bubbler and Shaggy for their help

Explanation:

¸                       #Split into words
 r                      #For each word, add them to the output in this way:
     i                  # Choose a character using this process:
       X·Ì              #  Get the last line of the output
          Y             #  And the current word
      [    ]¸           #  Join them with a space
             Ê>V?       #  If the resulting line is greater than the allowed length:
                ?R      #   Choose "/n" (newline)
                  :S    #  Otherwise choose " " (space)
     i                  # Add the chosen character to the output
  È+Y                   # Add the current word to the output
\$\endgroup\$
2
  • \$\begingroup\$ 24 bytes with [X,Y].join(...). \$\endgroup\$
    – Bubbler
    Dec 3, 2018 at 5:20
  • 1
    \$\begingroup\$ 20 bytes \$\endgroup\$
    – Shaggy
    Jan 9, 2019 at 17:19
1
\$\begingroup\$

Retina 0.8.2, 37 bytes

.+$
$*
!`(?=\S.*¶(1)+)(?<-1>.)+(?=\s)

Try it online! Takes s and n on separate lines. Explanation:

.+$
$*

Convert n to unary.

(?=\S.*¶(1)+)(?<-1>.)+(?=\s)

Match non-whitespace, then look ahead to n and count it as $#1. Then go back and use a balancing group to match up to n characters followed by whitespace.

!`

Output the matches as a list of lines.

\$\endgroup\$
2
  • \$\begingroup\$ Is there a way in Retina to put the first input in a regex we use with the second input? So something like this: .{1,50} and $0¶, but where 50 is received as input instead? \$\endgroup\$ Dec 5, 2018 at 10:55
  • \$\begingroup\$ @KevinCruijssen In Retina 1 you can probably use an Eval stage to give a similar result, but that's boring, so I didn't bother. \$\endgroup\$
    – Neil
    Dec 5, 2018 at 14:04
1
\$\begingroup\$

Charcoal, 19 bytes

Nθ←F⪪S «¿‹⁺LιⅈθM→⸿ι

Try it online! Link is to verbose version of code. Takes input of n and s on separate lines. Explanation:

Nθ

Input n.

Move the cursor left one square to balance the right movement from the first iteration of the loop.

F⪪S «

Split the string on spaces and loop over the words.

¿‹⁺Lιⅈθ

Calculate whether the next word will reach the right edge.

M→

If it will not then move one square right.

⸿

If it will then start a new line.

ι

Output the word.

\$\endgroup\$
1
\$\begingroup\$

JavaScript + HTML + CSS, 117 64 bytes

-53 bytes courtesy of @Neil

n=50
s="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat."
f=(n,s)=>document.body.innerHTML+=`<tt><p style=width:${n}ch>${s}`
f(n,s)

\$\endgroup\$
6
  • 1
    \$\begingroup\$ At least in my browser you can cut this down to (n,s)=>document.body.innerHTML+=`<p style=width:${n}ch><tt>${s}</tt></p>` for 74 bytes. If you're willing to dig out old versions of Firefox you can save another 8 bytes with (n,s)=>document.body.innerHTML+=`<pre wrap width=${n}>${s}</pre>` . \$\endgroup\$
    – Neil
    Dec 1, 2018 at 12:33
  • \$\begingroup\$ @Neil Nice use of ch units. Firefox 65 computes 50ch as 500px; Chromium 70 computes 50ch as 400px \$\endgroup\$ Dec 1, 2018 at 18:28
  • \$\begingroup\$ This answer is wrong. elit. Sed eget erat lectus. Morbi mi mi, fringilla sed (2nd line) is more than 50 characters. I'm using the newest Chrome. \$\endgroup\$
    – mbomb007
    Dec 1, 2018 at 19:59
  • \$\begingroup\$ I was able to tweak my original suggestion to work in Chrome by putting the <p> inside the <tt>. \$\endgroup\$
    – Neil
    Dec 1, 2018 at 20:16
  • 1
    \$\begingroup\$ next.plnkr.co/edit/fT2moRe5qgsxj48p?open=lib%2Fscript.js \$\endgroup\$
    – Neil
    Dec 1, 2018 at 20:29
1
\$\begingroup\$

Red, 125, 117, 114 112 bytes

func[s n][d: 0 parse s[any[to" "p:" "opt[[to" "| to end]q:(if(-1 - d + index? q)> n[p/1: #"^/"d: index? p])]]]s]

Try it online!

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 18 bytes

õs#vDy«g²›i,}yðJ}?

Try it online.

Explanation:

õ                   # Push an empty string "" to the stack
 s                  # Swap to take the (implicit) string input
  #                 # Split it by spaces
   v            }   # For-each `y` over the words:
    D               #  Duplicate the top of the stack
                    #  (which is the empty string in the very first iteration)
     y«             #  Append the current word `y`
       g            #  Get its length
        ²›i }       #  If its lengthy is larger than the second input:
           ,        #   Pop and output the current duplicated value with trailing newline
             yð     #  Push the word `y` and a space " "
               J    #  Join the entire stack together
                 ?  # After the loop, output the last part as well (without newline)
\$\endgroup\$
1
\$\begingroup\$

Java 8, 135 bytes

n->s->{String r="",S[]=s.split(" "),t=r;for(int i=0;i<S.length;)if((t+S[i]).length()>n){r+=t+"\n";t="";}else t+=S[i++]+" ";return r+t;}

Try it online.

Explanation:

n->s->{                      // Method with integer & String parameters and String return
  String r="",               //  Result-String, starting empty
         S[]=s.split(" "),   //  Input-String split by spaces
         t=r;                //  Temp-String, starting empty as well
  for(int i=0;i<S.length;)   //  Loop `i` in the range [0, amount_of_words):
    if((t+S[i]).length()>n){ //   If `t` and the word are larger than the integer input:
      r+=t+"\n";             //    Add `t` and a newline to the result
      t="";}                 //    And reset `t` to an empty String
     else                    //   Else:
       t+=S[i++]+" ";        //    Append the word and a space to `t`
                             //    (and then increase `i` by 1 with `i++` for the next word
                             //     of the next iteration)
  return r+t;}               //  Return the result-String appended with `t` as result
\$\endgroup\$
1
\$\begingroup\$

JavaScript, 40 bytes

s=>n=>eval(`s.match(/.{1,${n}}( |$)/g)`)

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Fail at the end \$\endgroup\$
    – l4m2
    Dec 3, 2018 at 4:26
  • \$\begingroup\$ @l4m2 fixed.... \$\endgroup\$
    – tsh
    Dec 3, 2018 at 5:02
0
\$\begingroup\$

Thanks to @Erik the Outgolfer, a golfed version :

Python 3, 94 bytes

def f(t,n):
 while t:i=n+(t[min(len(t)-1,n)]==" "or-t[n-1::-1].find(' '));print(t[:i]);t=t[i:]

Try it online!

# Python 3, 130 bytes

def f(t,n):
 l=[]
 while len(t):
  i=(n-t[:n][::-1].find(' '),n+1)[t[min(len(t)-1,n)]==" "]
  l.append(t[:i])
  t=t[i::]
 return l

Try it online!

Not so golfed version...

\$\endgroup\$
1
0
\$\begingroup\$

Jelly, 12 bytes

ḲŒṖK€€ḣ€ƑƇṪY

Try it online!

Unfortunately, this is too slow to work for the provided test case in under a minute over TIO.

\$\endgroup\$
0
\$\begingroup\$

C# (.NET Core), 162 bytes

string[]t(string n,int a){var g="";for(int i=0;i++<Math.Floor((double)n.Length/a);)g+=$"^.{{{i*a-1}}}|";return Regex.Split(n,$@"(?n)(?<=({g.Trim('|')})\S*)\s");}}

This function uses a regex which matches the closest whitespace that is near the nth or multiple of nth character and splits the string based on it.

Try it online!

The TIO link is a full program, and the function has a static keyword so the function can be called from main.

Test Regex

\$\endgroup\$
1
  • \$\begingroup\$ This doesn't give the right output for the test case - some lines are longer than 50 characters. You want "before" not "near", and also the splitting at one point must depend on where it was split earlier. \$\endgroup\$ Dec 3, 2018 at 9:14
0
\$\begingroup\$

C# (Visual C# Interactive Compiler), 78 bytes

s=>n=>System.Text.RegularExpressions.Regex.Replace(s,".{1,"+n+"}( |$)","$0\n")

Try it online!

Credit goes to @LukeStevens for coming up with the Java version... Apparently .NET makes you import the RegularExpressions namespace in order to do a replace :(

Here is my original version that splits on the space character and uses LINQ to join them back together:

C# (Visual C# Interactive Compiler), 91 bytes

s=>n=>s.Split(' ').Aggregate((a,w)=>a+(a.Length-a.LastIndexOf('\n')+w.Length>n?'\n':' ')+w)

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Dart, 112 bytes

f(s,n){var l=[''];s.split(' ').forEach((w){if((l.last+w).length<=n)l.last+=w+' ';else l.add(w+' ');});return l;}

Try it online!

\$\endgroup\$
0
\$\begingroup\$

APL(NARS), 48 chars, 96 bytes

{⊃⍵{⍺≥≢⍵:⊂⍵⋄k←1+⍺-' '⍳⍨⌽r←⍺↑⍵⋄(⊂k↑r),⍺∇k↓⍵}⍨⍺+1}

test:

  f←{⊃⍵{⍺≥≢⍵:⊂⍵⋄k←1+⍺-' '⍳⍨⌽r←⍺↑⍵⋄(⊂k↑r),⍺∇k↓⍵}⍨⍺+1}
  s←"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat."
  50 f s
Lorem ipsum dolor sit amet, consectetur adipiscing 
elit. Sed eget erat lectus. Morbi mi mi, fringilla 
sed suscipit ullamcorper, tristique at mauris.     
Morbi non commodo nibh. Pellentesque habitant      
morbi tristique senectus et netus et malesuada     
fames ac turpis egestas. Sed at iaculis mauris.    
Praesent a sem augue. Nulla lectus sapien, auctor  
nec pharetra eu, tincidunt ac diam. Sed ligula     
arcu, aliquam quis velit aliquam, dictum varius    
erat.                                              
\$\endgroup\$
1
  • \$\begingroup\$ I don't know in "{⊃⍵{⍺≥≢⍵:⊂⍵⋄..." If it is right ≥ or it is right there >... \$\endgroup\$
    – user58988
    Dec 26, 2018 at 20:17
0
\$\begingroup\$

C, 63 bytes

b(a,n)char*a;{while(strlen(a)>n){for(a+=n;*a-32;--a);*a++=10;}}

The function of this exercise b(a,n) would break the line "a" as exercise said, in the way not change its length (if we see the result as one string) because change some spaces in \n or new line in place. The input string "a" should have no \n character too in it for b() function (it could have \n in input string for bs())

b(a,n) function would be ok only because the restriction of this exercise, that impose each word of "a" string has length < n if this is not true, that function can go
to one infinite loop...(very wrong in my way of see so i copy too the function more good because in that case would return -1 and not would go to one infinite loop; it is bs(a,n) below)I not exclude both functions are bugged...

#define R(x,y) if(x)return y
#define U unsigned
U bs(char*a,U n)
{U c,q,r=1,i,j;
 R(!a||n<1||n++>0xFFFF,-1);
 for(j=c=i=0;;++i,++c)
    {R(i==-1,-1);q=a[i];
     if(q==10)goto l;
     if(c>=n){R(i-j>n,-1);a[i=j]=10;l:c=-1;++r;}
     R(!q,r);
     if(q==32)j=i;
    }
}

result of b() passed on one function that add line lenght each line

Lorem ipsum dolor sit amet, consectetur adipiscing [50]
elit. Sed eget erat lectus. Morbi mi mi, fringilla [50]
sed suscipit ullamcorper, tristique at mauris. [46]
Morbi non commodo nibh. Pellentesque habitant [45]
morbi tristique senectus et netus et malesuada [46]
fames ac turpis egestas. Sed at iaculis mauris. [47]
Praesent a sem augue. Nulla lectus sapien, auctor [49]
nec pharetra eu, tincidunt ac diam. Sed ligula [46]
arcu, aliquam quis velit aliquam, dictum varius [47]
erat. [5]
\$\endgroup\$
6
  • \$\begingroup\$ @ceilingcat ok, above code would make in consideration the \n too... one bug I found with the code was that the last line was not correctly print... why do you not write your C answer as other? It would win on mine because it is more short... for say the true I use the first line(or statement ";") for the check of input only because for me input has to be checked even if that is a little more long; I unsuccessful try to write the function in APL... \$\endgroup\$
    – user58988
    Dec 5, 2018 at 11:05
  • \$\begingroup\$ @ceilingcat in the last answer, seen that question not say if the input string have or not have to have in it '\n' char and seen that example not has '\n' I suppose input string has no new line character in it... \$\endgroup\$
    – user58988
    Dec 11, 2018 at 20:34
  • \$\begingroup\$ Only 83 ... Yes I have to see if I gain 3 chars using old function definition... \$\endgroup\$
    – user58988
    Dec 12, 2018 at 20:05
  • \$\begingroup\$ Just 81 .... .... .... \$\endgroup\$
    – user58988
    Dec 12, 2018 at 20:20
  • 1
    \$\begingroup\$ 60 bytes \$\endgroup\$
    – ceilingcat
    Dec 28, 2018 at 0:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.