Align the text to a block

10

Task

Your task is to write whole program, which will align given input to a block of given size.

Input:

40
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Output:

Lorem  ipsum dolor sit amet, consectetur
adipiscing  elit,  sed do eiusmod tempor
incididunt  ut  labore  et  dolore magna
aliqua.  Ut  enim  ad minim veniam, quis
nostrud   exercitation  ullamco  laboris
nisi ut aliquip ex ea commodo consequat.
Duis  aute  irure dolor in reprehenderit
in voluptate velit esse cillum dolore eu
fugiat  nulla  pariatur.  Excepteur sint
occaecat cupidatat non proident, sunt in
culpa  qui  officia deserunt mollit anim
id est laborum.
                <-- note the linebreak

Input Details

  • You have to write whole executable/interpretable program.
  • You may suppose, that the input contains only printable ASCII characters and does not contain tab \t.
  • The input can contain line breaks. If it does so, they are given as \n, \r, or \r\n depending on what you expect. They are however united throughout whole input.
  • The input can be given in STDIN, or as command line arguments. You can use both of them if it suits your needs (for example, read block size from command args and input as stdin). You may not, however, hardcode any part of the input to your program.
  • You may suppose that the block size is given as valid positive (> 0) number.
  • Line break in the input is treated the same way as a space (thus being word separator)
  • If the input contains multiple concurrent spaces they are treated as one.

Output details

  • The output has to be formatted into a block of given size. The formatting is done by adding spaces between words.
  • The number of spaces between words on a line has to be equal for that line. If it is not possible, additional spaces must be added one by one after words starting from the left.
  • If the word is longer that given block size, it will stand alone on a single line (and will exceed the block size).
  • If the output should contain only one word, it will be aligned to the left.
  • The last line of the output has to be aligned to the left, with only one space between words. The last line of the output has to end with trailing line break.

The answer, with shortest number of bytes after some time, wins.
If you need additional information, leave a comment.

Test cases

Input:
10
Lorem ipsum dolor sit amet,
consectetur adipiscing elit, sed do eiusmod tempor

Output:
Lorem
ipsum
dolor  sit
amet,
consectetur
adipiscing
elit,  sed
do eiusmod
tempor

Input:
20
Lorem     ipsum

dolor  sit amet,

Output:
Lorem   ipsum  dolor
sit amet,

Input:
1
Lorem ipsum dolor sit amet

Output:
Lorem
ipsum
dolor
sit
amet

Zereges

Posted 2015-10-20T10:32:06.807

Reputation: 1 165

Related. (Finally a second challenge for my [tag:typography] tag which already got auto-deleted. ;)) – Martin Ender – 2015-10-20T11:00:24.057

@MartinBüttner I didn't know that such tag exists. – Zereges – 2015-10-20T11:10:07.117

@Vɪʜᴀɴ You have to write whole executable/interpretable program. – Dennis – 2015-10-20T15:58:32.400

Duplicate of Justify a text by adding spaces.

– pppery – 2015-10-20T20:40:51.487

@ppperry Interesting, for some reason, it avoided my search skills – Zereges – 2015-10-20T21:40:31.517

@ppperry The rules for space insertion are quite substantially different though. – Martin Ender – 2015-10-21T06:10:08.847

Answers

2

Pyth, 60 57 54 51 50 52 bytes

2015-10-22: fixing a bug took 2 bytes.

=HfTcjd.zdWHAcH]f|qTlH>jd<HhTQ1s.iGcJ|tlG1*d?H-QlsGJ

Try it online.

PurkkaKoodari

Posted 2015-10-20T10:32:06.807

Reputation: 16 699

1

Ruby, 179 chars

n=gets.to_i
s=t=''
$<.read.split.map{|w|if(t+w).size>=n
0while t.size<n&&(1..n).any?{|i|t.sub!(/[^ ]#{' '*i}(?=[^ ])/){|x|x+' '}}
s+=t+?\n
t=w
else
t+=' '+w
t.strip!
end}
puts s,t

Way too long...

Semi-ungolfed version:

n = gets.to_i
s = t = ''
$<.read.split.map{|w|
    if (t + w).size >= n
        0 while t.size < n && (1..n).any?{|i|t.sub!(/[^ ]#{' '*i}(?=[^ ])/){|x|x+' '}}
        s += t + ?\n
        t = w
    else
        t += ' ' + w
        t.strip!  # this is only necessary because of the very first word >:(
    end
}
puts s,t

Doorknob

Posted 2015-10-20T10:32:06.807

Reputation: 68 138

0

CJam, 87 bytes

l~:LS*qNSerS%{(2$1$a+_S*,L>{;a\}{\;@;\}?}h;S*a]1>{I1>{LIs,-I,(md1b\aI,(*.+Sf*I.\}I?N}fI

This should still be golfable. Try it online in the CJam interpreter.

Dennis

Posted 2015-10-20T10:32:06.807

Reputation: 196 637

0

Retina, 133 bytes

\s+

+`((1)*1 )((?<-2>.)*\S|\S+) 
:$3<LF>$1
m+`^(?=.(.)+$[^<TB>]*^(?>(?<-1>1)+)1)((.*):(\S+ +)|(\S+ +)(.*):)
$3$4$5 :$6
+`:|<LF>1+| (?= .*$)
<empty>

The <empty> represents an empty trailing line. To run the code, put each line in a separate file, replace <LF> with linefeed characters (0x0A) and <TB> with a tab (0x09). I'll add an explanation when I'm done golfing.

Martin Ender

Posted 2015-10-20T10:32:06.807

Reputation: 184 808