# Right-align text

Your job is to take a string input and a number and align the string to the right, making the width of the text the number. When a line is too long, break it and put the rest on the next line, repeating until it's not necessary. If a line is shorter than the width, then pad it with spaces. Multiple newlines can occur, and should be treated like any other single character.

For example, the string

Programming
Puzzles
&
Code
Golf

and the number 5 would produce:

Progr
ammin
g
Puzzl
es
&
Code
Golf

Whereas the same string and the number 10 would produce:

Programmin
g
Puzzles
&
Code
Golf

The string

a

b

and the number 5 would produce:

a
<-- note the 5 spaces
b

Shortest code wins!

• The text says “Break the lines when necessary [...]”, but your examples suggest that you break after every word, even when it would fit. Please clarify: do we place each word on a new line, or do we implement an actual word-wrapping algorithm? Sep 24 '15 at 0:39
• Can there be spaces in the middle of an input line, e.g. Programming Puzzles\n&\nCode Golf? Sep 24 '15 at 2:04
• @sp3000 There can be any character, including spaces. Sep 24 '15 at 2:08
• @Timwi: The example has one word per line. It would have been better to include some multi-word lines to make it clear that space within a line isn't special. (i.e. there are only newlines, and non-newlines.) Sep 24 '15 at 8:58

## Python 2, 84

s,n=input()
for w in s.split('\n'):
w=w or' '
while w:print w[:n].rjust(n);w=w[n:]

Takes as input a string with newlines and a number, and prints the result. For each line in the input, takes and prints n chars at a time, using the built-in rjust to pad the left with spaces before printing.

I fixed the empty line case with the hack w=w or' '. There's probably a better method but I'm not going to think much about it.

jm.[\ QdscRQ.z

Demonstration

# CJam, 21 bytes

li_qN/Sfe|f/ff{\Se[N}

Thanks to @Sp3000 for golfing off 1 byte and paving the way for 3 more.

Try it online in the CJam interpreter.

### How it works

li                     Read an integer L from the first line of input.
_                    Push a copy.
qN/                 Split the remaining input at linefeeds.
Sfe|             Map OR " "'; the replaces empty lines with a space.
f/           Split each line into chunks of length L.
ff{     }  For each chunk, push L and the chunk; then:
\         Swap L with the chunk.
Se[      Left-pad the chunk to length L by prepending " ".
N     Push a linefeed.

# Pyth, 16

jm>Q+*\ QdscRQ.z

Try it online here

### Explanation

jm>Q+*\ QdscRQ.z             : Q is the number on the first line, .z takes the rest
cRQ.z             : chop each line of .z into chunks of Q characters
m        s                  : remove nested lists and map over the result
+*\ Qd                   : add Q spaces to each line d
>Q                         : take the last Q characters of that result
j                            : join results on newlines

# Perl, 39 bytes

perl -ni5 -e 's!^$|.{1,$^I}!printf"%${^I}s ",$&!ge'

36 bytes + 3 bytes for -ni. The wrap width is passed as the argument to -i.

Handles blank lines properly by padding them with spaces:

$echo -e "Programming\nPuzzles\n\n&\n\nCode\nGolf" | perl -ni5 -e 's!^$|.{1,$^I}!printf"%${^I}s
",$&!ge' Progr ammin g Puzzl es & Code Golf ## How it works This solution uses the substitution operator to loop through the input, saving a byte over the equivalent for loop. The real trick, though, is in the regex on the LHS of the substitution: ^$|.{1,$^I} With the global modifier, this will match$^I characters at a time; when there are less than $^I characters remaining in the string, it will match everything to the end. The alternation with ^$ is required to handle blank lines. For example:

$echo -e "foo\n\nbar" | perl -ni2 -E 'say "<$_>" for /^$|.{1,$^I}/g'
<fo>
<o>
<>
<ba>
<r>

The RHS of the substitution simply uses printf to left-pad the matched chunk with spaces.

• I always forget about $^I! Sep 24 '15 at 20:59 • @DomHastings I learned that trick from chilemagic, who mentioned it in a comment on another challenge. Sep 24 '15 at 21:11 # Javascript (ES6), 107 I wish JS had a built in pad function. Oh well. (a,b)=>a.replace(eval(/(.{${b}})(?!\\n)/g),$1 ).split .map(c=>(Array(b).join +c).slice(-b)).join  Explanation: (a, b)=> // searches for sequences of characters longer than b without a newline after them and // adds a newline after every b characters of the sequence a.replace(eval(/(.{${b}})(?!\\n)/g`), '$1\n') .split('\n') .map(c=> // prepends b spaces to each string then slices it from the right down to length b ( Array(b).join(' ') + c ).slice(-b) ).join('\n') # Julia, 126 bytes f(s,n)=for i=split(s,"\n") while length(i)>0 println(lpad(i[1:min(n,end)],n));length(i)<n?break:(i=i[min(n+1,end):end])end;end Ungolfed: function f(s::String, n::Int) for i in split(s, "\n") while length(i) > 0 println(lpad(i[1:min(n,end)], n)) length(i) < n ? break : (i = i[min(n+1,end):end]) end end end ## Bash, 62, 61+feature, 59 Shorter if N can be set by the caller, instead of having to read it as the first line of input. # width as a function arg: 59 chars f()while read -rn$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done # width on stdin: 64 chars (not updated with later suggestions&ideas) read N;while read -rn$N r;do [[ $r ]]&&printf %$N's\n' "$r";done This fails to handle empty lines in the input. Otherwise, this doesn't subject the input data to word-splitting, pathname expansion, or otherwise treat it as more than just raw data. read -n$N saves one character, but lets read munge \.

The [[ $r ]]&& is needed because read -n4 can't lookahead to see that the next char is a newline. So it sets r to a 4-char string, and the next read produces a zero-char empty string. Filtering these false newlines without filtering real newlines would require tracking state: whether the previous line was max-length or not. Either more code or a totally different approach would be needed. [[$r ]] is shorter than [ -n "$r" ] which is needed to avoid errors if the line starts with -z foo, or is * or something, if you used [$r ].

Justication happens with the standard printf "%4s" format string.

Test with

f()(while read -rn$1 r;do [[$r ]]&&printf %$1s\\n "$r";done); (echo 4; echo -e "*\n\\"; cat /tmp/lines) | f 4
• 1. I'd include -r in the byte count. 2. f()(while ... done) is a bit shorter. Sep 24 '15 at 6:36
• @Dennis: Without [[ $r ]]&&, if N=4, an input line of length 4 will produce a blank output line where there wasn't one before. Because read returns a string of 4 chars, then sees a newline on the next call and returns right away. Also, thanks for the () tip. I didn't know you could define fns that way. Sep 24 '15 at 6:37 • I recommend reading Tips for golfing in Bash. It's a great resource. Sep 24 '15 at 6:39 • Actually, since while is already compound, you don't even need the parentheses: f()while ... done Sep 24 '15 at 6:42 • @Dennis: wow, haxx. Thanks for the link. A couple of those things were new to me, and I fixed a couple things in another answer :) I don't normally golf, but >15 years of being a command-line junkie has taught me a thing or two :) Sep 24 '15 at 7:18 # Haskell, 108 bytes import Data.List.Split k[]=[""] k x=x f n=unlines.(map(\l->([1..n-length l]>>" ")++l).k.chunksOf n=<<).lines Usage example: *Main> putStr$ f 5 "a\n\nb\ncd\nMatamorphosis"
a

b
cd
Matam
orpho
sis

How it works

.lines   -- split input string at newlines
=<<         -- for every line
chunksOf n           --    split into chunks of length n
k                      --    fix empty lines
map                                --    for every chunk
\l->([1..n-length l]>>" "      --      make a string of missing spaces
++l            --      and append the chunk
unlines                                -- join padded chunks with newlines in-between

## GNU awk + bash, 70

f()(awk -vFPAT=.\{,$1} '{for(i=0;i++<NF;){printf "%'$1's\n",$i}}/^$/')

Using bash to slot the count into the awk program is prob. smaller than reading it with a NR==1{N=$0} block. Read a line at a time. Split into at-most-4 character chunks, using FPAT. (matches the fields, rather than the separators. GNU extension.) printf each field separately. (Default ORS = \n). The /^$/ rule is there to print empty lines, which have NF=0 and thus don't print at all in the other block. So unlike my pure-bash solution, this actually works in the general case.

Semi-unrelated, but my idea so far for perl is 112 chars for just the perl code:

(echo 4; echo -e 'foo\nbar'; echo -e "*\n\\"; echo '~$(true)'; cat /tmp/lines) | # test input perl -e '$N=<>;$/=\1;print "$N\n"; while(<>){if(/\n/ or length($l)>=$N){printf("%$4s\n",$l);$l=/\n/?"":$_;}else{$l.=$_;}}'

This eats one of the newlines, and is way too long. $/=\1 reads a byte at a time. We append to$l. Probably a line-at-a-time with fixed-width split approach would be shorter.

# Bash + GNU utils, 41

fold -$1|sed ":;s/^.\{,$[$1-1]\}\$/ &/;t"

String is input via STDIN, width is input by command-line arg:

ubuntu@ubuntu:~echo 'Programming Puzzles & Code Golf'|./ralign.sh 10 Programmin g Puzzles & Code Golf ubuntu@ubuntu:~

# Python 2, 151 bytes

s,n=input();N='\n'
for w in[i.lstrip()if i.replace(' ','').isalpha()else i for i in s.replace(N,'\n ').split(N)]:
while w:print w[:n].rjust(n);w=w[n:]

This is a adaptation of @xnor's answer above, as his does not properly handle newlines.

The for loop was changed from:

for w in s.split('\n'):

to:

for w in[i.lstrip()if i.replace(' ','').isalpha()else i for i in s.replace(N,'\n ').split(N)]:

function R(s,x){return s.replace(new RegExp(".{"+x+"}","g"),"$&\n").replace(/[^\n]*/g,function(m){ while(m.length<x)m=" "+m;return m;})} # Ceylon, 107 String w(String s,Integer n)=>"\n".join{for(l in s.lines)for(p in l.partition(n))String(p).padLeading(n)}; # Matlab, 99 bytes Thanks to @beaker for removing 6 bytes! Using and anonymous function: @(s,k)fliplr(char(cellfun(@fliplr,strsplit(regexprep(s,sprintf('\\S{%i}',k),'$0\n'),'\n'),'un',0)))

Define the function and use ans to call it:

>> @(s,k)fliplr(char(cellfun(@fliplr,strsplit(regexprep(s,sprintf('\\S{%i}',k),'$0\n'),'\n'),'un',0))) ans = @(s,k)fliplr(char(cellfun(@fliplr,strsplit(regexprep(s,sprintf('\\S{%i}',k),'$0\n'),'\n'),'un',0)))

>> ans(['Programming' 10 'Puzzles' 10 '&' 10 'Code' 10 'Golf'], 5) %% 10 is line feed

ans =

Progr
ammin
g
Puzzl
es
&
Code
Golf

## Burlesque, 28 Bytes

Same as the version below, but treats line 1 as the number and the other lines as the string.

lng_riPpun{pPco{pP' lp}mu}Wl

Usage as in:

\$ cat input.txt | blsq --stdin "lng_riPpun{pPco{pP' lp}mu}Wl"
Progr
ammin
g
Puzzl
es
&
Code
Golf

Old Version (16 bytes):

{5co{5' lp}mu}Wl

Example:

blsq ) "Programming\nPuzzles\n&\nCode\nGolf"{5co{5' lp}mu}Wl
Progr
ammin
g
Puzzl
es
&
Code
Golf