Esolang-Comment-Template-Generator

42

2

Lots of people on this site use esoteric languages, and since these languages are unusual and hard to understand, they will frequently write an explanation in a certain format. For example, if the code was

abcdefghijklmnop

And this languages uses # for comments, they would write an explanation like this:

a                #Explanation of what 'a' does
 bc              #Bc
   d             #d
    e            #Explanation of e
     fgh         #foobar
        ij       #hello world
          k      #etc.
           l     #so on
            mn   #and
              op #so forth

I frequently do this too, but every time I do this, I feel like creating the layout of text is really obnoxious and time-consuming. So I want you to create a "Esolang-Comment-Template-Generator" for me. For example, if we ignore the comments, the previous code has this template:

a                #
 bc              #
   d             #
    e            #
     fgh         #
        ij       #
          k      #
           l     #
            mn   #
              op #

The Challenge:

You must write a program or function that takes two strings as input, and outputs this "Esolang-Comment-Template". The first input will be the code, but with bars (|) inserted where the newlines go. The second input is what we will use for comments. So our last example would have this for input:

"a|bc|d|e|fgh|ij|k|l|mn|op", "#"

Unfortunately this excludes bars from being part of the code input, but that's OK. You can assume that the comment input will be a single character. For simplicity's sake, the comment char will not be a bar. The code input will only contain printable ASCII, and it will not contain any newlines.

Hopefully you can infer what to do from the testcases, but I'll try to clarify some things.

You must split the code input up into "code-sections" on every bar. Then, each section of code is output on its own line and left-padded with the length of all the previous code (not including the bars). Then, each line is right-padded with enough spaces so that the last two characters on every line are "One additional space" + "The comment character".

One trailing newline is allowed.

Here is another example. For the input

"Hello|World", "/"

The first section of code is "Hello" and the second is "World". So it should give the output:

Hello      /
     World /

Here are some more samples:

Input:
"a|b|c|d|e|f|g", ","

Output:
a       ,
 b      ,
  c     ,
   d    ,
    e   ,
     f  ,
      g ,

Input:
"abcdefg", ":"

Output:
abcdefg :

Input:
"4|8|15|16|23|42", "%"

Output:
4          %
 8         %
  15       %
    16     %
      23   %
        42 %

Input:
"E|ac|h s|ecti|on is| one c|haracte|r longer| than the| last!", "!"

Output:
E                                                   !
 ac                                                 !
   h s                                              !
      ecti                                          !
          on is                                     !
                one c                               !
                     haracte                        !
                            r longer                !
                                     than the       !
                                              last! !

Input:
"This|Code|has||empty||sections", "@"

Output:
This                     @
    Code                 @
        has              @
                         @
           empty         @
                         @
                sections @

Rules:

You may take these inputs and outputs in any reasonable format. For example, reading/writing a file, STDIN/STOUT, function arguments/return value, etc. As usual, this is , so try to make your code as short as possible and you win if you can get the shortest solution in your language! I will also select the shortest solution as the overall winner. Standard loopholes are banned.

James

Posted 2016-09-09T04:11:55.537

Reputation: 54 537

1Related – FryAmTheEggman – 2016-09-09T04:32:37.840

Are trailing blanks allowed? – Titus – 2016-09-09T09:02:51.297

30Next step : a 3D representation for 2D languages – Aaron – 2016-09-09T09:26:36.547

3A bonus if you manage to do it without using the | character would be nice, so you can explain yourself – WorldSEnder – 2016-09-09T12:11:55.317

Can the comment character be a bar (|) ? – Ton Hospel – 2016-09-12T08:46:24.843

Answers

6

Pyth - 28 27 24 23 bytes

Might be able to golf a little off. A lot off, apparently!

jt+R+;zC.t.u+*lNdYcQ\|k

Try it online here.

Maltysen

Posted 2016-09-09T04:11:55.537

Reputation: 25 023

9

Java 10, 189 159 bytes

s->c->{var r="";int p=0,i;for(var a:s.split("\\|")){for(i=p;i-->0;r+=" ");r+=a;for(p+=a.length();i++<s.replace("|","").length()-p;r+=" ");r+=c+"\n";}return r;}

-30 bytes converting Java 7 to Java 10 and optimizing the loops.

Try it online.

Explanation:

s->c->{                     // Method with String & char parameters and String return-type
  var r="";                 //  Result-String, starting empty
  int p=0,                  //  Position-integer, starting at 0
      i;                    //  Index integer
  for(var a:s.split("\\|")){//  Loop over the parts split by "|"
    for(i=p;i-->0;r+=" ");  //   Add `p` amount of spaces to the result-String
    r+=a;                   //   Add the current part to the result-String
    for(p+=a.length();      //   Add the length of the current part to the position-integer
        i++<s.replace("|","").length()-p;r+=" ");
                            //   Add the row's trailing spaces to the result-String
    r+=c+"\n";}             //   Add the character and a new-line to the result-String
  return r;}                //  Return the result-String

Kevin Cruijssen

Posted 2016-09-09T04:11:55.537

Reputation: 67 575

9

Retina, 35 34 bytes

Byte count assumes ISO 8859-1 encoding.

\|
·$'¶$`±
T0-2`·±|p`___ `.+±.|·.+

The two input strings are separated by a space (which is unambiguous since we know that the comment delimiter is always a single character).

Try it online!

Martin Ender

Posted 2016-09-09T04:11:55.537

Reputation: 184 808

1Why do you need a space to delimit the strings? Since it is a single character, it could just be the last one. – Adám – 2016-09-09T12:56:35.510

1@Adám I'm reusing it as the space separator in the final output. – Martin Ender – 2016-09-09T13:01:05.643

6

Pyke, 31 28 24 bytes

\|cDslF2l-hd*Q+Zi:il?+ZK

Try it here!

Blue

Posted 2016-09-09T04:11:55.537

Reputation: 26 661

4

JavaScript (ES6), 92 bytes

f=
(s,c)=>s.split`|`.map((_,i,a)=>a.map((e,j)=>i-j?e.replace(/./g,` `):e).join``+` `+c).join`
`
;
<div oninput=o.textContent=f(s.value,c.value)><input id=s placeholder=Code><input id=c size=1 maxlength=1 value=#><pre id=o>

Neil

Posted 2016-09-09T04:11:55.537

Reputation: 95 035

4

GNU sed (85 + 1 for -r) 86

:s;h;:;s,\|( *)[^ \|](.),|\1 \2,;t;s,\|,,g
p;g;:l;s,^( *)[^ \|],\1 ,;tl;s,\|,,;/\S/bs

The inputs are strings separated by a space.

Tests:
input.txt:

a|b|c|d|e|f|g ,
abcdefg :
4|8|15|16|23|42 %
E|ac|h s|ecti|on is| one c|haracte|r longer| than the| last! !
This|Code|has||empty||sections @

Output:

$ cat input.txt | sed -rf template
a       ,
 b      ,
  c     ,
   d    ,
    e   ,
     f  ,
      g ,

abcdefg :

4          %
 8         %
  15       %
    16     %
      23   %
        42 %

E                                                   !
 ac                                                 !
   h s                                              !
      ecti                                          !
          on is                                     !
                one c                               !
                     haracte                        !
                            r longer                !
                                     than the       !
                                              last! !

This                     @
    Code                 @
        has              @
                         @
           empty         @
                         @
                sections @

Riley

Posted 2016-09-09T04:11:55.537

Reputation: 11 345

The nameless label : is a GNU sed feature/bug and \S is I think an extension, so maybe the title should be GNU sed. Other than that, great code. – seshoumara – 2016-09-10T05:57:09.580

@seshoumara Thanks! – Riley – 2016-09-10T06:10:17.570

3

05AB1E, 29 38 31 29 bytes

'|„ǝʒ:'ǝ¡'ʒмεD®>úsg®+©s}.Bεð²J,

Can definitely be golfed, but at least its working now..
+9 bytes because ¡ (split) removes empty items automatically, so I had to add '|„ǝʒ:'ǝ¡'ʒм..
-2 bytes thanks to @MagicOctopusUrn by changing '|„ǝʒ:'ǝ¡'ʒм to '|¶:.BεðÜ} (current solution doesn't work on items with trailing spaces, but I've assumed that's allowed according to the test cases).

Try it online.

Explanation:

'|¶:           # Take the first input, and replace every "|" with "¶"
               #  i.e. "abc|d|e||fg" → "abc¶d¶e¶¶fg" (¶ are new-lines in 05AB1E)
    .B         # Box all the items (appending trailing whitespace to make it a rectangle)
               #  i.e. "abc¶d¶e¶¶fg" → ['abc','d  ','e  ','   ','fg ']
      εðÜ}     # Remove all trailing spaces from each item
               #  i.e. ['abc','d  ','e  ','   ','fg '] → ['abc','d,'e','','fg']
               #  NOTE: `'|¡` would have resulted in ['abc','d','e','fd'], hence the use of
               #        Box which implicitly splits on new-lines to keep empty items
ε              # For-each:
 D             #  Duplicate the current item
  ®>ú          #  Prepend global_variable + 1 amount of spaces
               #  (+1 because the global_variable is -1 by default)
               #   i.e. "e" and 3+1 → "    e"
 sg            #  Swap so the duplicated item is at the top, and take its length
   ®+          #  Sum it with the global_variable
               #   i.e. "e" (→ 1) and 4 → 5
     ©         #  And store it as new global_variable
      s        #  Then swap so the space appended item is at the end again
       }       # And end the for-each loop
.B             # Box all the items (appending the appropriate amount of spaces)
               #  i.e. ['abc','   d','    e','     ','     fg']
               #   → ['abc    ','   d   ','    e  ','       ','     fg']
ε              # For-each again:
 ð             #  A space character
  I            #  The second input-character
   J           #  Join both together with the current item
    ,          #  And print the current row with trailing new-line

Kevin Cruijssen

Posted 2016-09-09T04:11:55.537

Reputation: 67 575

This is invalid if the code were to contain ǝʒ. '|¶:.B could work tho. – Magic Octopus Urn – 2018-06-05T20:32:11.573

@MagicOctopusUrn The challenge description states "The code input will only contain printable ASCII, and it will not contain any newlines." Also, what part of the code should be replaced with '|¶:.B? – Kevin Cruijssen – 2018-06-05T20:42:47.750

I was thinking that'd be a shorter split, but it wouldn't work with your current code just slamming it in, you'd have to trim the excess. OR just ignore the excess and .B a second time after adding in the preceeding spaces. – Magic Octopus Urn – 2018-06-05T21:08:08.367

@MagicOctopusUrn It indeed might save some bytes, since my current work-around is pretty long, but it'll be harder to calculate the amount of preceeding spaces with the spaces after the .B already present. – Kevin Cruijssen – 2018-06-05T21:12:24.043

1'|¶:.BεðÜ}εD®>úsg®+©s}.BεðIJ,? 29 bytes. Back to iteration 1 :). .B splits on newlines, which is a feature not many people know. It's the only way I know of to keep empty elements. I'd request this as a feature. should mean split, but keep empty elements.. – Magic Octopus Urn – 2018-06-05T21:15:56.440

@MagicOctopusUrn Thanks. Indeed didn't knew .B implicitly splits on newlines. And using as split but keep empty items seems like a nice addition. – Kevin Cruijssen – 2018-06-06T06:42:07.270

3

Python 2, 125 124 132 bytes

-1 byte thanks to @TuukkaX (missed golfing the space from i, v)

def g(s,c):x=s.split('|');print((' '+c+'\n').join(' '*len(''.join(x[:i]))+v+' '*len(''.join(x[i+1:]))for i,v in enumerate(x))+' '+c)

All test cases on ideone

Jonathan Allan

Posted 2016-09-09T04:11:55.537

Reputation: 67 804

1Your supposed to use c as the comment char, not #. – Oliver Ni – 2016-09-11T01:01:13.753

@OliverNi - uh that was a hit for the code in its current form. – Jonathan Allan – 2016-09-11T01:10:17.133

3

Haskell, 139 135 bytes

s#p=j$foldl g("",0)s where g(a,n)c|c=='|'=(j(a,n)++"\n"++q n,n)|1>0=(a++[c],n+1);q m=' '<$[1..m];j(a,n)=a++q(sum[1|c<-s,c/='|']-n+1)++p

Saved 4 bytes by inlining a definition.

Ungolfed:

template :: String -> String -> String
template code comment = format $ foldl g ("", 0) code
    where g (acc, n) c
            | c == '|' = (format (acc, n) ++ "\n" ++ spaces n, n)
            | otherwise = (acc ++ [c], n+1)
          l = length $ filter (/= '|') code
          spaces n = replicate n ' '
          format (acc, n) = acc ++ spaces (l-n+1) ++ comment

sudee

Posted 2016-09-09T04:11:55.537

Reputation: 551

3

Groovy, 120 113 111 Bytes

def m(s,c){s.split(/\|/).inject(0,{e,t->println((' '*e+t).padRight(s.replace('|','').size()+1)+c);e+t.size()})}

ungolfed*

def m(s,c){
  s.split(/\|/).inject(0, { e, t ->
    println((' '*e+t).padRight(s.replace('|','').size())+' '+c)
    e+t.size()
  })
}

(First Draft with 120 Bytes)

def m(s,c){def l=0;s.split(/\|/).collect{l+=it.size();it.padLeft(l).padRight(s.replace('|','').size())+' '+c}.join('\n')}

ungolfed*

def m(s,c){
  def l=0 // minimized version needs a semicolon here
  s.split(/\|/).collect{
    l+=it.size() // minimized version needs a semicolon here
    it.padLeft(l).padRight(s.replace('|','').size())+' '+c
  }.join('\n')
}

Tests

%> m('a|bc|d|e|fgh|ij|k|l|mn|op', '#')
a                #
 bc              #
   d             #
    e            #
     fgh         #
        ij       #
          k      #
           l     #
            mn   #
              op #

%> m('Hello|World', '/')
Hello      /
     World /

%> m('a|b|c|d|e|f|g', ',')
a       ,
 b      ,
  c     ,
   d    ,
    e   ,
     f  ,
      g ,

%> m('abcdefg', ':')
abcdefg :

%> m('4|8|15|16|23|42', '%')
4          %
 8         %
  15       %
    16     %
      23   %
        42 %

%> m('E|ac|h s|ecti|on is| one c|haracte|r longer| than the| last!', '!')
E                                                   !
 ac                                                 !
   h s                                              !
      ecti                                          !
          on is                                     !
                one c                               !
                     haracte                        !
                            r longer                !
                                     than the       !
                                              last! !

%> m('This|Code|has||empty||sections', '@')
This                     @
    Code                 @
        has              @
                         @
           empty         @
                         @
                sections @

norganos

Posted 2016-09-09T04:11:55.537

Reputation: 51

How about .padRight(s.replace('|','').size()+1)+c) – AmazingDreams – 2016-09-09T11:57:40.917

good idea! thank you! saved another 2 chars! – norganos – 2016-09-09T12:55:52.460

3

Python 2, 107 105 102 99 bytes

Tested with all test cases above

EDIT Golfed off 2 bytes by changing d=a.split("|");i=0 to d,i=a.split("|"),0 Not sure how I missed that one. Thanks @Oliver Ni

Another 3 bytes gone. Thanks again.

Suggestion from @Jonathan actually saves 3 bytes and takes it down to the magic 99. Thanks.

def c(a,b):
 d,i=a.split("|"),0
 for e in d:j=i+len(e);print" "*i+e+" "*(len("".join(d))-j+1)+b;i=j

ElPedro

Posted 2016-09-09T04:11:55.537

Reputation: 5 301

Golfed it down 6 bytes – Oliver Ni – 2016-09-10T03:59:53.163

1Golfed it down another byte – Oliver Ni – 2016-09-10T04:04:09.653

3

Hey @OliverNi , providing tips for golfing stuff down is appreciated, but editing code isn't really appropriate on this site (source), so I've rolled back your edit. Feel free to post those tips as a comment though! I'm sure the OP would appreciate it, but it should be up to them to test it and choose if they want to use it.

– James – 2016-09-10T14:04:50.877

1Thanks to both of you. Firstly to @Oliver for taking the interest and the time to improve my humble effort and secondly to DJMcMayhem for clarifying what I believed to be the case but had not had a chance to comment on. Oliver - thanks again and please feel free to post changes as comments so that I can learn from your golfing experience. – ElPedro – 2016-09-10T18:25:33.757

1You can remove the parenthesis around " "*i to ave 2 bytes – Oliver Ni – 2016-09-10T20:55:48.283

Also, change len("".join(d))-(i+len(e)-1) to len("".join(d))-i-len(e)+1 to save another two bytes – Oliver Ni – 2016-09-10T20:56:58.663

1You can also set a variable to len(e) like for e in d:z=len(e).... to save a byte because it is used twice – Oliver Ni – 2016-09-10T20:59:00.317

Tips 1 and 3 worked but 2 seemed to mess up the formatting of the comment characters (not in a vertical line). Maybe I am missing something? – ElPedro – 2016-09-10T21:17:54.637

Hmm... I tworks for me – Oliver Ni – 2016-09-10T23:02:56.863

It's just the distributive property – Oliver Ni – 2016-09-10T23:03:17.270

1Take it down to a nice round 100 with this as your for loop: for e in d:j=i+len(e);print" "*i+e+" "*(len("".join(d))-j+1)+b;i=j – Jonathan Allan – 2016-09-11T01:02:34.903

2

PowerShell v2+, 103 99 bytes

param($a,$b)$a-split'\|'|%{" "*$l+$_+" "*(($a-replace'\|').length+1-$_.length-$l)+$b;$l+=$_.Length}

Takes input as two strings, -splits the first on literal pipe (since split uses regex syntax), and feeds the elements into a loop |%{...}.

Each iteration, we construct a string as being a number of spaces defined by $l concatenated with the current element. For the first loop, $l initializes to $null, which gets evaluate here as 0.

That string is further concatenated with another number of spaces (defined by how long $a would be if we -replaced every pipe with nothing, plus 1 for the additional padding between code and comments, minus the .length of the current element, minus $l which is how many spaces we padded left on this iteration), concatenated with our comment character $b. That's left on the pipeline.

We then update $l for the next iteration.

The resultant strings are all left on the pipeline, and output via implicit Write-Output happens at program execution, with a newline between them by default.

Examples

PS C:\Tools\Scripts\golfing> .\esolang-comment-template-generator.ps1 "This|Code|has||empty||sections" "@"
This                     @
    Code                 @
        has              @
                         @
           empty         @
                         @
                sections @

PS C:\Tools\Scripts\golfing> .\esolang-comment-template-generator.ps1 "a|bc|def|ghi|h" "|"
a          |
 bc        |
   def     |
      ghi  |
         h |

AdmBorkBork

Posted 2016-09-09T04:11:55.537

Reputation: 41 581

2

Vim, 39 38 keystrokes

-1 byte thanks to DJMcMayhem

Expects as input a buffer (e.g. a file) whose first character is the comment delimiter, followed by the code, e.g. #foo|bar|baz.

"cxqaf|m`Yp<Ctrl+o>v$r jv0r x@aq@a$p<Ctrl+v>gg$C <Ctrl+r>c<Esc>

Explanation

("_" denotes a literal space.)

"cx          " Delete the first character (the comment delimiter) and store in register 'c'
qa           " Start recording macro 'a'
f|m`         " Advance to the first '|' on the line and set mark
Yp<Ctrl+o>   " Duplicate this line and return to mark
v$r_         " Replace everything after the cursor on this line (inclusive) with spaces
jv0r_x       " Go down a line and replace everything before the cursor on this line (inclusive) with
             "   spaces, then delete one space
@a           " Call macro recursively
q@a          " Stop recording and immediately call the macro
$p           " Paste the deleted space at the end of the last line
<Ctrl+v>gg$       " Highlight the column where the comment delimiters will go and all trailing spaces
C_<Ctrl+r>c<Esc>  " Replace the highlighted text on each line with a space and the contents of
                  "   register 'c' (the comment delimiter)

Jordan

Posted 2016-09-09T04:11:55.537

Reputation: 5 001

1:D I always upvote vim! I think you could take one byte off if you change mm to m\`` and then change`mto<C-o>` – James – 2016-09-09T22:33:30.617

@DJMcMayhem Thanks! I love golfing in Vim because I always learn something about a tool I use every day. – Jordan – 2016-09-10T15:14:45.670

2

Floroid - 94 bytes

Ah(a,b):c=a.fn("|");z(" "+b+"\n".y(' '*Z("".y(c[:j]))+l+" "*Z("".y(c[j+1:]))Kj,lIai(c))+' '+b)

Uses an approach similar to @JonathanAllans' Python solution.

Testcases

Call: h("a|bc|d|e|fgh|ij|k|l|mn|op", "#")
Output: 
a                #
 bc              #
   d             #
    e            #
     fgh         #
        ij       #
          k      #
           l     #
            mn   #
              op #

Yytsi

Posted 2016-09-09T04:11:55.537

Reputation: 3 582

2

C# 176 167 154 bytes

string f(string s,char x){var c=s.Split('|');var d="";int i=0;foreach(var b in c)d+=b.PadLeft(i+=b.Length).PadRight(s.Length+2-c.Length)+x+"\n";return d;}

UnGolfed

string f(string s, char x)
{
    var c = s.Split('|');
    var d = "";
    int i = 0;
    foreach (var b in c)
        d += b.PadLeft(i += b.Length).PadRight(s.Length + 2 - c.Length) + x + "\n";
    return d;
}

A LINQ solution would have been 146 but needed using System.Linq; bringing it back up to 164:

string f(string s,char x){var c=s.Split('|');int i=0;return c.Aggregate("",(g,b)=>g+b.PadLeft(i+=b.Length).PadRight(s.Length+2-c.Length)+x+"\n");}

Old solutions:

167 bytes:

string f(string s,char x){var c=s.Split('|');var d="";int i=0;foreach(var b in c){d+=b.PadLeft(i+b.Length).PadRight(s.Length+2-c.Length)+x+"\n";i+=b.Length;}return d;}

176 bytes using string interpolation

string f(string s,char x){var c=s.Split('|');var d="";int i=0;foreach(var b in c){d+=string.Format($"{{1,{i}}}{{0,-{s.Length+2-c.Length-i}}}{x}\n",b,"");i+=b.Length;}return d;}

pinkfloydx33

Posted 2016-09-09T04:11:55.537

Reputation: 308

1

Funky, 89 bytes

s=>c=>{y=0forn inl=s::split"|"print((v=" "::rep)(y)+l[n]+v((#l::reduce@++1)-y+=#l[n])+c)}

Try it online!

ATaco

Posted 2016-09-09T04:11:55.537

Reputation: 7 898

1

PHP, 120 117 116 110 109 bytes

foreach($a=split('\|',$argv[1])as$i=>$t){$c=preg_replace('#.#',' ',$a);$c[$i]=$t;echo join($c)," $argv[2]
";}

or

foreach($a=split('\|',$argv[1])as$t){$c=preg_replace('#.#',' ',$a);$c[$i++|0]=$t;echo join($c)," $argv[2]
";}

Titus

Posted 2016-09-09T04:11:55.537

Reputation: 13 814

1

MATL, 33 31 bytes

'\|'0'|'hYXo8M&YbY:&YdtaZ)0ihYc

Try it online!

Explanation

The builtin function Yd (blkdiag), which builds a block-diagonal matrix from its inputs, does most of the work. The fill values in the matrix are 0, and char 0 is treated as a space for displaying purposes. The code would simply split on |, build a matrix from the resulting blocks, convert to char, and append two columns with space and comment symbol.

However, the possibility of empty sections in the input string complicates makes the problem more interesting: the resulting block would be empty and thus wouldn't show in the resulting matrix.

To solve this, we introduce a char 0 before each |, so no block will be empty; and then in the resulting char matrix we remove columns that are formed by char 0 only. A non-empty code section will have some printable ASCII char, and thus the columns it spans will survive. An empty section will contribute a row, but won't introduce an extra column.

'\|'    % Push this string: source for regexp matching. It's just | escaped
0'|'h   % Push a string formed by char 0 followed by | (no escaping needed)
YX      % Input string implicitly. Replace first of the above string by the second
o       % Convert from chars to code points. Gives a numeric vector
8M      % Push '|' again
&Yb     % Split numeric vector at occurences of | (the latter is automatically
        % converted  to its code point). This gives a cell array of numeric vectors
Y:      % Unbox cell array: pushes the numeric vectors it contains
&Yd     % Form a block-diagonal matrix from those vectors
ta      % Duplicate. Compute vector that equals true for columns that have some
        % nonzero value
Z)      % Used that as a logical index (mask) for the columns of the matrix.
        % This removes columns that contain only zeros
0ih     % Input comment symbol and prepend char 0 (which will be displayed as space)
Yc      % Append that to each row of the matrix. The matrix is automatically 
        % converted from code points to chars
        % Display implicitly

Luis Mendo

Posted 2016-09-09T04:11:55.537

Reputation: 87 464

1I'm vaguely disappointed that you didn't put your explanation in the format the OP mentioned – Random832 – 2016-09-09T18:30:29.430

1@Random832 I don't use that format often. It uses up a lot of space, leaving little room for the explanations – Luis Mendo – 2016-09-09T18:37:30.267

Why is the escape needed in the first string? – Conor O'Brien – 2016-09-11T04:04:58.323

@ConorO'Brien Good question. I never know which/when special symbols need escaping and which/when not. In this case, | (match subexpression before or after the |) does need it, at least in the Matlab/Octave regexp engine – Luis Mendo – 2016-09-11T11:01:03.257

1

Dyalog APL 16.0 (non-competing), 43 37 bytes

Prompts for comment character, then for code.

↑(↓↑((-(⍸'|'∘=),≢)↑¨'|'∘≠⊆⊢)⍞),¨⊂¯2↑⍞

Non-competing because version 16.0's is newer than this challenge.

Adám

Posted 2016-09-09T04:11:55.537

Reputation: 37 779

How is dyalog APL non-competing still? Is it still in-dev? – James – 2016-09-10T15:59:51.163

@DJMcMayhem Yes. I work for Dyalog and have had access to 16.0 even before 15.0 was released. 16.0 is scheduled for release in 2017Q1. – Adám – 2016-09-10T20:22:09.823

How does this work? – Conor O'Brien – 2016-09-12T00:30:47.500

1

Pyth, 30 bytes

VJcE\|s[*ZdN*h--lsJZlNdQ)=+ZlN

or

jm+dQ.t.t+MC,.u*l+NYdJc+Ed\|kJ

Both are full programs that take input on STDIN of the comment string, and then the program string, newline-separated.

Try the first version online

Try the second version online

How they work

VJcE\|s[*ZdN*h--lsJZlNdQ)=+ZlN  Program. Inputs: E, Q
  cE\|                          Split E on "|"
 J                              Assign to J
                                Implicit Z=0
V                               For N in that:
       [                )        Create a list with elements:
        *Zd                       Z spaces
           N                      N
               -lsJZ              len(concatenate(J))-Z
              -     lN             -len(N)
             h                     +1
            *         d            spaces
                       Q          Q
      s                          Concatenate the list
                                 Implicitly print
                        =+ZlN    Z=Z+len(N)

jm+dQ.t.t+MC,.u*l+NYdJc+Ed\|kJ  Program. Inputs: E, Q
                       +Ed      Add a trailing space to E
                      c   \|    Split that on "|"
                     J          Assign to J
             .u                 Cumulatively reduce J with:
                            k    starting value empty string and
                                 function N, Y ->
                l+NY              len(N+Y)
               *    d             spaces
            ,                J  Two-element list of that and J
           C                    Transpose
         +M                     Map concatenation over that
       .t                       Transpose, padding with spaces
     .t                         Transpose again
 m+dQ                           Map concatenation with Q over that
j                               Join on newlines
                                Implicitly print

TheBikingViking

Posted 2016-09-09T04:11:55.537

Reputation: 3 674

1

Perl, 63 bytes

Includes +5 for -Xpi

Run with input on STDIN and comment character after -i:

perl -Xpi% esolang.pl <<< "Ab|Cd||ef"

esolang.pl:

s/
/|/;s%(.*?)\|%$"x$`=~y/|//c.$1.$"x$'=~y/|//c." $^I
"%eg

Totally boring straightforward solution

Ton Hospel

Posted 2016-09-09T04:11:55.537

Reputation: 14 114

1

Turtlèd, 35 bytes (noncompeting)

Takes one input, the last character is the comment character. Does not work with comment character as space, but I assume that isn't necessary.

!' [*.+(|' dl)r_]' r[*+.(|u)_][ .d]

Explanation:

!                                  take input into string variable
 '                                 write space over current cell
   [*           ]                  while cell is not *
     .+                            write pointed char of string, stringpointer+1 (starts 0)
       (|    )                     if current cell is |
         ' dl                      write space (over |), move down, left
              r_                   move right, write * if pointed char is
                                   last char, else space

                 ' r               write space, move right
                    [*       ]     while cell is not *
                      +.           increment pointer and write pointed char
                        (|u)       if cell is |, move up
                            _      write * if the pointed char is the last char

                              [   ] while cell is not space
                                .d  write the pointed char from string, move down 

Destructible Lemon

Posted 2016-09-09T04:11:55.537

Reputation: 5 908

0

Jelly, 10 bytes

ṣ”|⁶ṁ;ɗ\pG

Try it online!

Erik the Outgolfer

Posted 2016-09-09T04:11:55.537

Reputation: 38 134

0

Ruby, 96 80 bytes

->s,c{s.gsub(/(^|\|)([^|]*)/){" "*$`.count(t="^|")+$2+" "*(1+$'.count(t))+c+$/}}

See it on eval.in: https://eval.in/639012

I really ought to just learn Retina.

Jordan

Posted 2016-09-09T04:11:55.537

Reputation: 5 001

0

Scala, 123 bytes

def?(i:String,c:String)={var b=0
i.split('|').map{s=>println(" "*b+s+" "*(i.replace("|","").size-b-s.size+1)+c)
b+=s.size}}

Test code + Output:

?("a|b|c|d|e|f|g", ",")
a       ,
 b      ,
  c     ,
   d    ,
    e   ,
     f  ,
      g ,

?("abcdefg", ":")
abcdefg :

?("4|8|15|16|23|42", "%")
4          %
 8         %
  15       %
    16     %
      23   %
        42 %

?("E|ac|h s|ecti|on is| one c|haracte|r longer| than the| last!", "!")
E                                                   !
 ac                                                 !
   h s                                              !
      ecti                                          !
          on is                                     !
                one c                               !
                     haracte                        !
                            r longer                !
                                     than the       !
                                              last! !

?("This|Code|has||empty||sections", "@")
This                     @
    Code                 @
        has              @
                         @
           empty         @
                         @
                sections @

AmazingDreams

Posted 2016-09-09T04:11:55.537

Reputation: 281

0

GolfScript, 85 bytes

{(;);}:r;", "%(r\(r n+:c;;.,\'|'%.,@\-)):l;0:m;{.,0>}{" "m*\(.,m+:m l\-" "\*+c@}while

Try it online

2017 Update - GolfScript - 71 bytes

', '/~~:c;~1/.,\.{'|'=},,@\-):l;['|']/0:i;{.,i+:i l i-' '*c+\' '*"
"\}/

Explanation

', '/~~:c;~1/        # Parses input
.,\.{'|'=},,@\-):l;  # Computes string length without '|'
['|']/               # Splits the array
0:i;                 # Counter
{.,                  # Length of the substring
i+:i                 # Counter update
l i-' '*c+\          # Adds spaces after the substring 
' '*"\n"\            # Adds spaces before the next substring
}/                   # ...For each substring

FedeWar

Posted 2016-09-09T04:11:55.537

Reputation: 271

0

Jelly, 41 bytes

This looks like it has far to many increments, and probably too many links...

ṫø⁹‘‘µFL‘⁶ẋ
‘ị
ḣFL⁶ẋ$;ç@;1ŀ
J’ç@€
ṣ”|Ç;€Y

Test it at TryItOnline

How?

ṫø⁹‘‘µFL‘⁶ẋ  - link 1: get the spaces for after the code, dyadic(split string, index)
 ø           - next chain as a nilad
  ⁹‘‘        - right argument incremented twice (the index we actually want)
ṫ            - tail (get the rest of the split string)
     µ       - next chain as a monad
      FL‘    - flatten, get its length and increment
         ⁶   - a space character " "
          ẋ  - repeat the space character that many times

‘ị           - Link 2: get the code for a line dyadic(index, split string)
‘            - increment the index
 ị           - retrieve the string at that index

ḣFL⁶ẋ$;ç@;1ŀ - Link 3: get the code and join with spaces, dyadic (index, split string)
ḣ            - head: split string[index:]
 FL          - flatten and get its length
     $       - previous two atoms as a monad
   ⁶         - a space character, " "
    ẋ        - repeat the space that many times
      ;      - concatenate with
       ç@    - the result of the previous link (the code) - reverse inputs
         ;   - concatenate with
          1ŀ - the result of Link 1 (the spaces after the code)

J’ç@€        - Link 3: a for loop, monadic(split string)
J’           - [0,...,Len(split string)-1]
  ç@€        - the result of the previous link, with revered inputs, for each

ṣ”|Ç;€Y      - Main Link: dyadic(code string, comment character)
ṣ”|          - split on "|"
   Ç         - the result of the previous link
    ;€       - concatenate each with the comment character
      Y      - join with line feeds
             - implicit print

Jonathan Allan

Posted 2016-09-09T04:11:55.537

Reputation: 67 804

0

CJam, 32 bytes

l'|/_s,)L@{1$,S*\+}%@f{Se]}lN+f+

Explanation

l                                  get code string
 '|/                               split into code parts
    _s,)                           length of all the parts +1
        L@{1$,S*\+}%               left pad spaces to every part for the length of the previous parts
                    @f{Se]}        right pad spaces
                           lN+f+   add comment character and newline

Try it online

Neorej

Posted 2016-09-09T04:11:55.537

Reputation: 179