Center The Text!

40

3

Center The Text!

In this challenge you will be centering various lines.

Examples

Foo
barbaz

 Foo
barbaz
Hello
World

Hello
World
Programming Puzzles
&
Code Golf

Programming Puzzles
         &
     Code Golf

Specifications

Each input line will always have at least one non-whitespace character, you may assume the only whitespace character are spaces () and newlines. Each input line won't have any trailing and/or leading whitespace (except for the newline). Trailing whitespace in the output is not allowed.

You should be centering among the longest line in the input. If that line is even in length, your program/function should prefer to center to the left. The maximum line length is whatever your language can handle but your program should function on lines of at least 500 in length.


Leaderboard

Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

# Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

# Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

# Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the leaderboard snippet:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

var QUESTION_ID=66731,OVERRIDE_USER=8478;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

This is so shortest code in bytes wins!

Downgoat

Posted 2015-12-16T01:35:32.043

Reputation: 27 116

There will never be more than one inner-space? – cat – 2015-12-16T01:41:54.403

@cat there will never be any leading whitespace or trailing whitespace on a line (expect for the newline if there is one) – Downgoat – 2015-12-16T01:43:30.823

yes, but I mean inner-spaces, like, between words – cat – 2015-12-16T01:45:43.767

1@cat oh, between words there may be more than one whitespace. For example foo(space)(space)(space)bar is a perfectly acceptable input – Downgoat – 2015-12-16T01:46:43.570

can we assume there will always be more than 1 line? – GamrCorps – 2015-12-16T01:54:30.193

@GamrCorps I'd say no, your program should still work even if only one line is given as input. – Downgoat – 2015-12-16T01:58:32.653

What about trailing spaces? Forbidden, optional, or mandatory? – Timwi – 2015-12-16T04:00:50.650

@Timwi I'll say trailing/leading whitespace isn't allowed. – Downgoat – 2015-12-16T04:02:05.500

I'm not sure you mean when you say you don't want leading whitespace in the output. The first line in your output example " Foo" has a leading whitespace. – Willem – 2015-12-16T04:42:48.750

@Willem I meant additional leading newlines added by the program, I've clarified – Downgoat – 2015-12-16T04:43:34.203

@Downgoat I think if you edit your question Specifications by replacing "Each line" by "Each input line" that will clarify things. – Willem – 2015-12-16T04:52:58.423

OK, glad you clarified that, however you should be aware that this renders most of the existing answers invalid. – Timwi – 2015-12-16T05:16:19.383

Answers

15

Pyth, 19 17 bytes

2 bytes thanks to Jakube

V.ztr+1.[l.T.zNd6

Demonstration

I think this is the first time the center-pad function of .[ has been useful. The length of the longest line is found using non-truncating transpose (.T).

Trailing spaces are removed by adding a non-space character to the front, stripping spaces, then removing the added character.

isaacg

Posted 2015-12-16T01:35:32.043

Reputation: 39 268

1We probably need a max length in array. It comes up way too often. +1 – Maltysen – 2015-12-16T02:28:41.753

The specifications say that "Trailing whitespace in the output is not allowed." This appears to have trailing whitespace on each short line in the output, so I'm not sure it counts. – potato – 2015-12-16T05:55:42.787

@potato Thanks - that was added since I answered. – isaacg – 2015-12-16T06:39:45.697

31

vim, 43 36 35 bytes

VGrx:sor
G:let &tw=col("$")
uu:%ce

Too good not to post. Note the trailing newline; it is significant.

Thanks to @Marth for saving a character!

vim-friendly format:

VGrx:sor<cr>G:let &tw=col("$")<cr>uu:%ce<cr>

Explanation:

VGrx                   replace every character with an "x"
:sor<cr>               sort (since all chars are now same, sorts by line length)
G                      go to the very last line
:let &tw=col("$")<cr>  set &tw to column number of last char on this line
                         "let &tw" is equivalent to "set tw"
                         tw is short for textwidth, used in :center
uu                     undo the sort, and the replacing-with-x too
:%ce<cr>               center over entire file (%), using textwidth set earlier

Doorknob

Posted 2015-12-16T01:35:32.043

Reputation: 68 138

1Surely this should all be done in Insert mode, right? – Alex A. – 2015-12-16T02:38:25.813

9@AlexA. None of it is done in insert mode. ಠ_ಠ – Doorknob – 2015-12-16T02:40:00.970

If you use sor! to reverse the sort order, you can use col("$") to get the length of the first line (now the longest since the order is reversed) instead of using G$, saving a grand total of 1 byte! edit: or you could keep the sort order and use G:let &tw=col("$") instead. – Marth – 2015-12-16T12:05:58.907

@Marth Thanks! I chose the latter (for no particular reason). – Doorknob – 2015-12-16T12:19:23.097

Looking through :h :sort I just found out that you can pass a regex to skip the matching text in the sort, so you can use :sor /./ to sort on length (+4 bytes), which lets you remove the VGrx (-4 bytes) and the second undo (-1 bytes). You can also use | separators instead of <cr> to chain the commands, which lets you skip the : before let (-1 bytes) (note that you have to use the sor! solution then, G is not an ex command). So :sor! /./|let &tw=col("$")|u|%ce (with a trailing <CR>) should save 2 bytes. – Marth – 2015-12-16T12:42:03.840

@Marth Alas, :sor! /./ does not seem to be sorting by length, like you said it should. – Doorknob – 2015-12-16T13:12:17.050

@Doorknob冰: Erf, you're right. I could have sworn it worked when I tried it, but you need to use :sor /.*/ for it to work, which means it doesn't save any byte… oh well – Marth – 2015-12-16T13:22:59.803

23

Mathematica, 96 bytes

StringRiffle[#~StringPadLeft~Floor[Max@(l=StringLength)@a/2+l@#/2]&/@(a=#~StringSplit~"
"),"
"]&

Don't ask me how it worked, I just fiddled with it until it produced the correct output.

LegionMammal978

Posted 2015-12-16T01:35:32.043

Reputation: 15 731

27+1 for "Don't ask me how it worked, I just fiddled with it until it produced the correct output" – cat – 2015-12-16T03:13:11.080

4@cat That's how I do all my golfing. – lirtosiast – 2015-12-17T04:37:52.707

11

Funciton, non-competitive

This challenge has highlighted the sore lack of a “maximum value” (and minimum value) function for lazy sequences, so... I added them to the core library (they’re called ⊤ and ⊥, respectively). Therefore I didn’t bother to submit this as a golfed answer (it would have to include the ⊤ function declaration to be valid), so here’s just the main program.

Execute (function(){$('pre,code').css({lineHeight:5/4,fontFamily:'DejaVu Sans Mono'});})() in your browser console to get some nicer rendering.

   ╓───╖         ╔════╗  ┌───╖  ╔═══╗
 ┌─╢ ‡ ╟─┐       ║ 10 ╟──┤ ǁ ╟──╢   ║
 │ ╙───╜ │       ╚════╝  ╘═╤═╝  ╚═══╝
 │ ┌───╖ │  ┌──────────────┴──────────────────┐
 └─┤ ‼ ╟─┘┌─┴─╖ ┌───╖ ┌───╖ ┌───╖ ┌───╖       │     │
   ╘═╤═╝  │ ɱ ╟─┤ ⊤ ╟─┤ + ╟─┤ ~ ╟─┤ ℓ ╟───┐ ┌─┴─╖ ┌─┴─╖ ╔════╗
     │    ╘═╤═╝ ╘═══╝ ╘═╤═╝ ╘═══╝ ╘═══╝   │ │ ɱ ╟─┤ ʝ ╟─╢ 10 ║
    ┌───╖ ╔═╧═╕ ╔═══╗ ┌─┴──╖ ┌───╖ ╔════╗ │ ╘═╤═╝ ╘═══╝ ╚════╝
  ┌─┤ ℓ ╟─╢   ├─╢ 1 ║ │ >> ╟─┤ … ╟─╢ 32 ║ │   │
  │ ╘═══╝ ╚═╤═╛ ╚═╤═╝ ╘═╤══╝ ╘═╤═╝ ╚════╝ │ ╔═╧═╕ ╔═══╗
  └─────────┘     └─────┘      │   ┌───╖  ├─╢   ├─╢ 0 ║
                               └───┤ ‡ ╟──┘ ╚═╤═╛ ╚═══╝
                                   ╘═╤═╝      │
                                     └────────┘

Explanation

I believe this may be the first Funciton answer on this site that uses lambda expressions.

  • First, we use ǁ to split the input string at the newlines (ASCII 10). This returns a lazy sequence.
  • We pass that sequence through ɱ (map), giving it a lambda that calculates the length of each string, and then pass the final sequence through to get the length of the longest line.
  • We also pass that sequence through another ɱ, giving it a lambda that calculates the length of each string, subtracts it from the maximum line length calculated earlier, divides that by 2 (actually shift-right 1), generates that many spaces (ASCII 32) and then concatenates the string onto those spaces. (For geometric reasons, I declared a function that calls (string concatenate) with the parameters reversed.)
  • Finally, we use ʝ to put all of the strings back together, using newlines (ASCII 10) as the separator.

Timwi

Posted 2015-12-16T01:35:32.043

Reputation: 12 158

+1 for how awesome this is and "That’s 716 characters, totaling 1,508 bytes"

– cat – 2015-12-20T18:57:02.447

9

Retina, 54 52 bytes

+m`^(.)+$(?<=(?=[^\t]*^..(?<-1>.)+(?(1)^))[^\t]*)
 $0 

The \ts can replaced with actual tabs, but I've used \t here, because otherwise SE will convert the tabs to spaces. Note that there is a leading space on the second line.

Try it online.

Explanation

The basic idea is to match a line which is at least two characters shorter than the longest line (or technically, two characters shorter than any other line), and surround it in two spaces. This is repeated until we can no longer find such a line, which means that all lines are within one character of the maximum length (where the one character is to account for parity mismatches, and guarantees that these lines are shifted to the left off-centre).

As for the actual regex:

^(.)+$

Just matches any one line while pushing one capture onto group 1 for each character.

(?<=...[^\t]*)

Is a lookbehind which is matched right-to-left and moves the cursor to the beginning of the string, so that the lookahead inside can check the entire string. Note that due to a lack of an anchor, the lookahead could be applied from anywhere else, but that does not create additional matches. We know that [^\t] will always match any character in the string, because the input is guaranteed to contain only spaces and linefeeds as far as whitespace is concerned.

(?=[^\t]*^..(?<-1>.)+(?(1)^))

This lookahead tries to find a line which is at least two characters longer than the one we're currently matching. [^\t]* moves through the string in order to be able to match any line. ^ ensures that we're starting from the beginning of the line. .. then matches the two additional characters we require for the longer line. Now (?<-1>.)+ matches individual characters in that line while popping from group 1 (note that . cannot match a linefeed, so this is constrained to one line). Finally, (?(1)^) asserts that we managed to empty the entire group 1. If the line is shorter than required, this is not possible, because there are not enough characters in the line to pop from group 1 often enough to empty it.

Martin Ender

Posted 2015-12-16T01:35:32.043

Reputation: 184 808

7

CJam, 26 23 19 bytes

qN/_z,f{1$,m2/S*\N}

My first time using CJam! Four bytes saved thanks to Martin Büttner. Try it online.

Explanation

qN/    e# Read input and split each line
_z,    e# Transpose a copy and get its length to find the longest line
f{     e# For each line...
  1$,- e# Subtract its length from the longest length
  2/   e# Divide by two to get just the spaces to add to the left
  S*\  e# Add a string with that many spaces to the beginning
  N    e# Add a newline to go on to the next line
}

NinjaBearMonkey

Posted 2015-12-16T01:35:32.043

Reputation: 9 925

1Here are some suggestions :) qN/_z,f{1$,m2/S*\N} – Martin Ender – 2015-12-16T08:28:57.410

7

Jolf, 3 bytes

Noncompeting, update postdates question.

Try it here!.

pci
pc  center
  i  string input

¯\_(ツ)_/¯ I thought it'd be a useful function.

Conor O'Brien

Posted 2015-12-16T01:35:32.043

Reputation: 36 228

1This is a standard loophole, and while not explicitly dis-allowed, its bad form unless its built into a language you find, not one you create. – Elias Benevedes – 2015-12-17T00:36:18.077

3@EliasBenevedes I added the feature before the contest. I don't often update my code until it becomes relavent. – Conor O'Brien – 2015-12-17T00:39:17.470

7

JavaScript (ES6), 93 91 bytes

s=>(m=l=s.split`
`).map(x=>(v=x.length/2)<m?v:m=v).map((x,i)=>" ".repeat(m-x)+l[i]).join`
`

2 bytes saved thanks to @edc65!

Explanation

s=>(
  m=                // m = max line length (divided by 2)
    l=s.split`
`)                  // l = array of lines
.map(x=>            // for each line
  (v=x.length/2)    // v = current line length / 2
    <m?v:m=v        // set m to the max line length and return v
)
.map((x,i)=>        // for each line length / 2
  " ".repeat(m-x)   // add spaces before
    +l[i]           // add line text
)
.join`
`                   // return lines as a newline-separated string

Test

var solution = s=>(m=l=s.split`
`).map(x=>(v=x.length/2)<m?v:m=v).map((x,i)=>" ".repeat(m-x)+l[i]).join`
`
<textarea id="input" rows="4" cols="20">Programming Puzzles
&
Code Golf</textarea><br />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>

user81655

Posted 2015-12-16T01:35:32.043

Reputation: 10 181

.repeat accepts and truncates non-integer values, so you don't need |0 – edc65 – 2015-12-16T11:10:40.570

6

Python 2, 83 81 bytes

def f(s):
 t=s.split('\n')
 for y in t:print(max(len(f)for f in t)-len(y))/2*' '+y  

Thanks to @xnor for saving 2 chars

example input:

f("""Programming Puzzles
&
Code Golf""")

example output:

Programming Puzzles
         &
     Code Golf

And ending in second place with 84 bytes using str.center() and str.rstrip (thanks @J F).

def f(s):
 t=s.split('\n')
 for y in t:print y.center(max(len(f)for f in t)).rstrip()

Willem

Posted 2015-12-16T01:35:32.043

Reputation: 1 528

It doesn't save chars to assign len to a variable you use twice -- that breaks even at 5 chars (like range). Also, you can use map for the list comp. – xnor – 2015-12-16T05:59:33.407

@Willem, you could use str.rstrip() after calling center to get rid of the trailing space. – J F – 2015-12-19T16:33:57.083

You can save 7 bytes with a full program and using len(max(a,key=len)), see this.

– ბიმო – 2018-04-23T12:05:46.887

6

LabVIEW, 3 or 35 LabVIEW Primitives

Finds lines until none are left, then calculates how many spaces to add and puts everything together.

Alternatively you could use the built-in center alignment on string indicators, it kinda does feel like cheating though.

Eumel

Posted 2015-12-16T01:35:32.043

Reputation: 2 487

5

TeaScript, 24 bytes

£p.R((aßln)¯-ln)/2)+l,§)

Loops through lines, adds floor((max line length - line length) / 2) spaces to the beginning.

Ungolfed

£   p.R((aß  ln)¯  -ln)/2)+l,§   )
xl(#p.R((am(#ln)X()-ln)/2)+l,`\n`)

xl(#    // Loops through newlines
    p.R(   // Repeats spaces
      (
       am(#ln)    // Map all line lengths
              X() // Get largest line length
       -ln)       // Subtract current line length
      /2)  // Divide by two
      +l,  // Add current line text
`\n`)

Try it online

Downgoat

Posted 2015-12-16T01:35:32.043

Reputation: 27 116

5Why do my answers keep getting Downgoated? I think it's time to change the username / avatar :p – Downgoat – 2015-12-17T04:25:54.430

Fixed as of 2016-07-27. :P – user48538 – 2016-07-27T15:51:16.983

5

PowerShell, 58 67 bytes

down to 58 bytes thanks to @mazzy's comments:

param($a)$a|%{$_|% *ft(($a|% le*|sort)[-1]/2+$_.length/2)}


# It takes an array of strings as input
PS C:\Temp> .\center.ps1 'aaa','bb','c'
aaa
bb
 c


# Or here, read from a file
PS C:\Temp> .\center.ps1 (gc t.txt)
info0:info1:info2:info3
      info0:info1
          ttt
          tt
           t
  • It takes an array of strings as $a, loops over each string with |%{...}.
  • calls the string.padleft() method on each string, via % -member shortcut, which takes desired final line length as a parameter.
    • we need array_longest_line_length/2 + current_line_length/2
    • the end part is current_line_length/2 -> $_.length/2
    • the other part is recalculating the array's maximum line length every time through the loop, and it does so with a nested loop making an array of line lengths, sorts that, then takes the last one.

TessellatingHeckler

Posted 2015-12-16T01:35:32.043

Reputation: 2 412

you can use Shortening Property Names and Length of elements to get 58 bytes

– mazzy – 2019-03-19T18:24:22.960

1@mazzy that is better! since you didn't post as an answer, I've edited that into my answer with credit. – TessellatingHeckler – 2019-03-20T05:48:02.077

3

Emacs Lisp, 203 bytes

(let((f 0)(l 0))(dolist(s(split-string(buffer-string)"\n"))(set'l(string-width s))(when(> l f)(set'f l)))(let((fill-column f))(goto-char(point-min))(while(<(point)(point-max))(center-line)(next-line)))))

Ungolfed:

(let ((f 0) (l 0))
  (dolist (s (split-string(buffer-string) "\n"))
    (set 'l (string-width s))
    (when (> l f)
      (set 'f l)))
    (let ((fill-column f))
      (goto-char (point-min))
      (while (< (point) (point-max))
        (center-line)
        (next-line)))))

Centered:

               (let ((f 0) (l 0))
 (dolist (s (split-string(buffer-string) "\n"))
           (set 'l (string-width s))
                 (when (> l f)
                  (set 'f l)))
             (let ((fill-column f))
            (goto-char (point-min))
         (while (< (point) (point-max))
                 (center-line)
                (next-line)))))

Lord Yuuma

Posted 2015-12-16T01:35:32.043

Reputation: 587

3

HTML, 40 bytes

<xmp style=float:left;text-align:center>

<xmp style=float:left;text-align:center>
Programming Puzzles
&
Code Golf
</xmp>

Snippet includes </xmp> tag because the code snippet viewer wants my tags to be balanced.

Neil

Posted 2015-12-16T01:35:32.043

Reputation: 95 035

2

MATL, 22 31 bytes

`jtYz~]xXhc4X4H$ZuZ{Zv

Each line is input with a trailing line (that is, an enter keystroke). An empty line (two enter keystrokes) marks the end of input.

Example

>> matl `jtYz~]xXhc4X4H$ZuZ{Zv
> foo
> barbaz
> 
 foo
barbaz

Explanation

`          % do...
  j        % input one string
  tYz~     % is it not empty?
]          % ...while
x          % delete last input (empty string)
Xh         % concatenate all inputs into a cell array
c          % convert to char (2D array). This fills with spaces to the right
4X4H$Zu    % center justify
Z{         % convert to cell array of strings
Zv         % remove trailing blanks of each string

Luis Mendo

Posted 2015-12-16T01:35:32.043

Reputation: 87 464

2

Ruby, 76 68 61 bytes

->t{(s=t.split$/).map{|l|l.center(s.map(&:size).max).rstrip}}

Sample run:

2.1.5 :001 > puts ->t{(s=t.split$/).map{|l|l.center(s.map(&:size).max).rstrip}}["Programming Puzzles\n&\nCode Golf"]
Programming Puzzles
         &
     Code Golf

manatwork

Posted 2015-12-16T01:35:32.043

Reputation: 17 865

53 bytes: ->t{(s=t.split$/).map{|l|l.center s.map(&:size).max}} – daniero – 2015-12-16T21:54:40.333

I also tried the center way first, but as I understand, that alone would break the “Trailing whitespace in the output is not allowed” rule. Thank you for the &:size part – I also tried that too, but I certainly banged something around the syntax. – manatwork – 2015-12-17T07:35:40.053

2

Haskell, 111 81 77 bytes

l=length
f s|q<-lines s=unlines[([1..div(maximum(l<$>q)-l w)2]>>" ")++w|w<-q]

Input to the f function, the output is not printed.

Usage: load in interpreter ghci center.hs and then if you want to print the output of f on a given string putStr$f"Programming Puzzles\n&\nCode Golf"

Edit: Thanks to nimi for 34 bytes, great job! :D

basile-henry

Posted 2015-12-16T01:35:32.043

Reputation: 381

Two more things: The latest version of the Prelude includes an infix version of map: <$>. replicate(...)' ' can be replaced by [1.. ...]>>" ". All in all: unlines[([1..div(maximum(l<$>q)-l w)2]>>" ")++w|w<-q]. – nimi – 2015-12-17T15:38:05.840

Ah yes I remember you mentioning the new map infix in a previous submission I made. How does the replicate trick work? – basile-henry – 2015-12-17T15:45:53.333

l1 >> l2 makes (length l1) copies of l2 and concatenates them. E.g. "abcd" >> [1,2] -> [1,2,1,2,1,2,1,2] (<- 4 copies of 1,2 in a single list). In our case it's [1..n]>>" " which is n copies of a space which is the same as what replicate does. – nimi – 2015-12-17T15:51:16.160

Nice, thanks for the explanation! :) – basile-henry – 2015-12-17T15:52:56.777

2

R, 126 bytes

code

for(z in 1){l=scan(,"");m=sapply(l,nchar);t=max(m[m==max(m)]);for(i in 1:length(m))cat(rep(" ",(t-m[i])/2),l[i],"\n", sep="")}

ungolfed

for(z in 1){                          # any way to get rid of this?
  l=scan(,"")
  m <- sapply(l,nchar)
  t <- max(m[m==max(m)])
  for(i in 1:length(m)){
    cat(rep(" ",(t-m[i])/2),l[i],"\n", sep="")
  }
}

Probably there are waay better ways to do this, still working on it.

Mutador

Posted 2015-12-16T01:35:32.043

Reputation: 1 361

1

Gema, 160 bytes

\L<T>=@push{i;$0}@set{m;@cmpn{@length{$0};${m;};$m;$m;@length{$0}}}
?=
\Z=@repeat{@sub{@line;1};@set{o;@right{@div{@add{$m;@length{$i}};2};$i}\n${o;}}@pop{i}}$o

Written mostly for my curiosity to see what can be done in a language without proper array structure and proper loop instruction.

Sample run:

bash-4.3$ gema '\L<T>=@push{i;$0}@set{m;@cmpn{@length{$0};${m;};$m;$m;@length{$0}}};?=;\Z=@repeat{@sub{@line;1};@set{o;@right{@div{@add{$m;@length{$i}};2};$i}\n${o;}}@pop{i}}$o' <<< $'Programming Puzzles\n&\nCode Golf'
Programming Puzzles
         &
     Code Golf

manatwork

Posted 2015-12-16T01:35:32.043

Reputation: 17 865

1

Perl 6, 61 bytes

$/=(my@l=lines)».chars.max;for @l {put ' 'x($/-.chars)/2~$_} # 61 bytes

usage:

$ perl6 -e '$/=(my@l=lines)».chars.max;for @l {put " "x($/-.chars)/2~$_}' <<< \
'Programming Puzzles
&
Code Golf'
Programming Puzzles
         &
     Code Golf

Brad Gilbert b2gills

Posted 2015-12-16T01:35:32.043

Reputation: 12 713

Perl 5 would allow you to drop the spaces in things like for @l {, shaving 2 bytes, and to change put " " to put" ", shaving another byte. Is that true for Perl 6? (I don't know Perl 6.) Also, your output as displayed here doesn't match the required output; is that a typo? – msh210 – 2015-12-17T17:42:43.010

@msh210 Perl 6 is a bit more restrictive with its syntax. It more than makes up for it in other areas though. – Brad Gilbert b2gills – 2015-12-18T03:08:57.160

1

Japt, 28 25

¡V=VwXl}R;¡Sp½*(V-Xl¹+X}R

Try it online!

How it works

¡     V=VwXl}R;¡     Sp½*(V-Xl¹ +X}R
UmXYZ{V=VwXl}R;UmXYZ{Sp½*(V-Xl) +X}R

           // Implicit: U = input string, V = 0
UmXYZ{  }  // Map each item X in U through this function,
         R // splitting U at newlines beforehand:
  V=VwXl   //  Set V to max(X, Y.length).
           // V is now set to the length of the longest line.

UmXYZ{  }  // Map each item X in U with this function,
         R // again splitting U at newlines beforehand:
 ½*(V-Xl)  //  Take V minus X.length, and multiply by 1/2.
Sp         //  Repeat a space that many times.
        +X //  Concatenate X to the end.

ETHproductions

Posted 2015-12-16T01:35:32.043

Reputation: 47 880

0

PHP, 98 bytes

function($s){foreach($a=explode("
",$s)as$l)echo str_pad($l,max(array_map(strlen,$a)),' ',2),"
";}

Try it online!

Ungolfed:

function str_center( $s ) {
    $a = explode( PHP_EOL, $s );
    $m = max( array_map( 'strlen', $a ) );
    foreach( $a as $l ) {
        echo str_pad( $l, $m, ' ', STR_PAD_BOTH ), PHP_EOL;
    }
}

Output:

Programming Puzzles
         &         
     Code Golf   

640KB

Posted 2015-12-16T01:35:32.043

Reputation: 7 149

-1

05AB1E, 2 bytes

.c

Builtins ftw ¯\_(ツ)_/¯

Try it online or verify all test cases.

Explanation:

.c   # Centralize the (implicit) multi-line input-string with preference to the left
     # (output the result implicitly)

(Preference to the right would be with a capital .C instead: see the differences.)

Kevin Cruijssen

Posted 2015-12-16T01:35:32.043

Reputation: 67 575

-1

Shaggy

Posted 2015-12-16T01:35:32.043

Reputation: 24 623