Given a string n, create a pyramid of the string split into pieces relative to the current row.

The first row contains the string unmodified.

The second row contains the string separated into halves by a pipe.

The third row separates it by thirds...

And so on. The length of each substring, where l is the length of string n is equal to


Characters left over are put in their own substring. The last row used is the first one where substrings are 2 in length.

Test Cases:

Input: Hello, world.


Hello, world.

Hello,| world|.

Hell|o, w|orld|.

Hel|lo,| wo|rld|.

He|ll|o,| w|or|ld|.

Input: abcdefghij






Input: 01234567890abcdef








Extra rules:

  • You can write a full program or a function, whichever uses less code.

  • Input will always be at least 4 characters in length.

  • You MUST use line breaks if your language supports them. If not possible, replace line breaks with :

  • Input will always be printable ASCII.

  • Minus 100% if your program solves P vs. NP.


var QUESTION_ID=104297,OVERRIDE_USER=62384;function answersUrl(e){return"http://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"http://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>

  • \$\begingroup\$ 0 bytes: return: false \$\endgroup\$ Commented Dec 23, 2016 at 14:29
  • 3
    \$\begingroup\$ Nice first challenge! A few clarification questions -- is the input only printable ASCII (I strongly suggest "yes")? What does "line breaks are necessary when possible" mean? \$\endgroup\$ Commented Dec 23, 2016 at 14:39
  • 3
    \$\begingroup\$ It's a joke. P vs NP is an unsolved problem in computing. The joke is that if you can solve it, I will stop caring about the fact the your program doesn't solve the challenge. \$\endgroup\$ Commented Dec 23, 2016 at 19:24
  • 3
    \$\begingroup\$ The real unsolved problem in computing is "tabs or spaces"... \$\endgroup\$
    – FlipTack
    Commented Dec 23, 2016 at 22:49
  • 3
    \$\begingroup\$ No, the real problem is Internet Explorer. \$\endgroup\$ Commented Dec 23, 2016 at 22:50

9 Answers 9


Perl, 46 + 1 = 47 bytes

Run with the -n flag

say s/.{$=}(?=.)/$&|/gr while($==y///c/++$,)-2

Try it online!

Code breakdown

-n                                              #Reads input into the $_ variable
say s/.{$=}(?=.)/$&|/gr while($==y///c/++$,)-2
                                 y///c          #Transliteration.  Implicitly operates on $_, replacing every character with itself and counting replacements
                                                #y///c effectively returns the length of $_
                                      /++$,     #Increments $, (which starts off at 0) and divides the length of $_ by $,
                              $==               #Stores the result of this division into $=
                                                #$= forces its contents to be an integer, so it truncates any decimal
                             (             )-2  #Returns 0 if $= is equal to 2
                        while                   #Evaluates its RHS as the condition.  If truthy, evaluates its LHS.
    s/          /   /gr                         #Substitution.  Implicitly operates on $_.
                                                #Searches for its first argument and replaces it with its second argument, repeating until it's done, and returns the new string.  $_ is not modified.
      .{$=}                                     #Looks for a string of $= characters...
           (?=.)                                #...that is followed by at least one non-newline character, but does not include this character in the match...
                 $&|                            #...and replaces it with itself followed by a pipe character.
say                                             #Output the result of the substitution.
  • \$\begingroup\$ This doesn't seem to work for longer inputs. \$\endgroup\$
    – Neil
    Commented Dec 24, 2016 at 0:16

Pyth, 16 bytes


V                # For N in range(1, \/ )
 h/lQ3           # 1+lenght(input)/3
      j\|        # join with '|'
         cQ      # chop input in
           /lQhN # lenght(input)/(N+1) pieces

try here

  • 1
    \$\begingroup\$ This might work for the test cases but I don't think it works for longer inputs. \$\endgroup\$
    – Neil
    Commented Dec 24, 2016 at 0:15

C, 145 131 128 125 bytes


This is a function that takes a string as its argument and prints the output to STDOUT.

l,n,i=1,j;       // declare some variables
f(char*s){       // declare the function
l=strlen(s);     // get the length of the string
puts(s);         // output the initial version, with trailing newline
do{n=l/++i;      // n is the number of characters per "section",
                 //  and we'll do-while n>2 to stop at the right time
for(j=0;j<l;)    // loop through the characters of the string
j&&(             // if j != 0,
j%n||            // and j % n == 0,
putchar('|')),   // insert a | before this character
putchar(s[j++]); // print the character
puts("");        // print a newline after the loop
  • \$\begingroup\$ How does this work once i*i>l? It looks as if it will start to repeat sections. \$\endgroup\$
    – Neil
    Commented Dec 24, 2016 at 0:13
  • \$\begingroup\$ @Neil I'm not sure what you mean. Could you give an example? \$\endgroup\$
    – Doorknob
    Commented Dec 24, 2016 at 0:16
  • \$\begingroup\$ @Neil Ah, never mind, I see what you're saying. That appears to be a hole in the specification, which explicitly states that the length of each substring is floor(l/n); I'm not sure what the intended behavior is for longer inputs or if the OP anticipated that. \$\endgroup\$
    – Doorknob
    Commented Dec 24, 2016 at 0:19

Pyth, 17 bytes



     cQ/lQ         Divide into equal pieces (with the last shorter)
  j\|              Join with pipes
 m        d        Map to each row index...
           Sh/lQ3  ... up to the first row with substrings of length 2
j                  Join with newlines

Javascript, 98 Bytes


Function x(a). Call using



JavaScript (ES6), 103 101 91 84 bytes

Fixed to respect challenge requirements


Lambda f that takes input string as first parameter s and recursively prints to console the split string. Pretty straightforward: as long as the substring length, p, is above 1, print the string split by a '|' every p characters, then proceed with appending the following level. This then calls the function again with p being t / n floored, where t is the original string length and n being an incremented divider.

  • \$\begingroup\$ I don't think dividing n by 2 each time is correct. \$\endgroup\$
    – Neil
    Commented Dec 24, 2016 at 0:12
  • \$\begingroup\$ @Neil you are correct, mistake on my part. I fixed the problem and saved 2 bytes in the process. \$\endgroup\$
    – user62802
    Commented Dec 24, 2016 at 13:37
  • \$\begingroup\$ @ETHproductions I thought of that, but I don't know if that would count as STDOUT... I guess I would need to do alert(f(s)) just after right? \$\endgroup\$
    – user62802
    Commented Dec 24, 2016 at 18:33

Python 3, 123 bytes

f=lambda s:print(*['|'.join(s[i:i+n]for i in range(0,len(s),n))for n in[len(s)//i for i in range(1,len(s)//2+1)]],sep='\n')

At longer strings some parts will be repeated, as the formula for the length of the substring is floor(l/n). For example with a string 13 chars long, the string split into 5's would be the same as the string split into 6's as floor(13/5)==floor(13/6). I'm not sure if the OP expected this or if it was an oversight.


Ruby -n, 60 bytes

z= ~/$/
(z/3+1).times{|n|puts $_.scan(/.{1,#{z/(n+1)}}/)*?|}

Attempt This Online!


Vyxal, 13 bytes


Try it Online!

12 with j flag


₌Lż            # Push len(input) and [1..len(input)]
   ḭ           # Floor divide the length by each number in the range
    vẇ         # And wrap the input into chunks of each length
      UṪ       # Uniquify the list and remove the last item (which will be the input split into chunks of length 1)
        \|vj   # Join each list on "|"
            ⁋  # And join that on newlines

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.