20
\$\begingroup\$

There are several ways to create headers on posts on the Stack Exchange network. The format that's most commonly1 used on PPCG seems to be:

# Level one header
## Level two header
### Level three header

Note the space after the hash marks. Also, note that trailing hash marks are not included.

Challenge:

Take a (possibly multiline) string as input, and output the string on the following format:

  • If the header is level 1, then output each letter 4-by-4 times
  • If the header is level 2, then output each letter 3-by-3 times
  • If the header is level 3, then output each letter 2-by-2 times
  • If a line is not a header then output it as it is.

To illustrate:

--- Level 1 ---
# Hello
--- Output---
HHHHeeeelllllllloooo    
HHHHeeeelllllllloooo
HHHHeeeelllllllloooo
HHHHeeeelllllllloooo

--- Level 2 ---
## A B C def
--- Output ---
AAA   BBB   CCC   dddeeefff
AAA   BBB   CCC   dddeeefff
AAA   BBB   CCC   dddeeefff

--- Level 3 ---
### PPCG!
--- Output---
PPPPCCGG!!
PPPPCCGG!!

Simple as that!


Rules:

  • You must support input over multiple lines. Using \n etc. for newlines is OK.
    • There won't be lines containing only a # followed by a single space
  • The output must be presented over multiple lines. You may not output \n instead of literal newlines.
    • Trailing spaces and newlines are OK.

Test cases:

Input and output are separated by a line of ....

# This is a text
with two different
### headers!
........................................................    
TTTThhhhiiiissss    iiiissss    aaaa    tttteeeexxxxtttt
TTTThhhhiiiissss    iiiissss    aaaa    tttteeeexxxxtttt
TTTThhhhiiiissss    iiiissss    aaaa    tttteeeexxxxtttt
TTTThhhhiiiissss    iiiissss    aaaa    tttteeeexxxxtttt
with two different
hheeaaddeerrss!!
hheeaaddeerrss!!

This input has
## trailing hash marks ##
#and a hash mark without a space after it.
........................................................    
This input has
tttrrraaaiiillliiinnnggg   hhhaaassshhh   mmmaaarrrkkksss   ######
tttrrraaaiiillliiinnnggg   hhhaaassshhh   mmmaaarrrkkksss   ######
tttrrraaaiiillliiinnnggg   hhhaaassshhh   mmmaaarrrkkksss   ######
#and hash marks without a space after it.

# This ## is ### strange
#### ###
........................................................
TTTThhhhiiiissss    ########    iiiissss    ############    ssssttttrrrraaaannnnggggeeee
TTTThhhhiiiissss    ########    iiiissss    ############    ssssttttrrrraaaannnnggggeeee
TTTThhhhiiiissss    ########    iiiissss    ############    ssssttttrrrraaaannnnggggeeee
TTTThhhhiiiissss    ########    iiiissss    ############    ssssttttrrrraaaannnnggggeeee
#### ###

Multiple


### newlines! # 
:)
........................................................    
Multiple


nneewwlliinneess!!  ##
nneewwlliinneess!!  ##
:)

Line with only a hash mark:
#
### ^ Like that!
........................................................    
Line with only a hash mark:
#
^^  LLiikkee  tthhaatt!!
^^  LLiikkee  tthhaatt!!

1: I haven't really checked, but I think it's true.

\$\endgroup\$
  • \$\begingroup\$ May we take input as a string array? \$\endgroup\$ – Ian H. Nov 16 '17 at 21:56

16 Answers 16

7
\$\begingroup\$

Stacked, 51 50 bytes

Saved 1 byte thanks to @RickHitchcock - golfed regex

['^(##?#?) (.+)'[\#'5\-@k CS k*k rep LF#`]3/mrepl]

Try it online!

Anonymous function that takes input from the stack and leaves it on the stack.

Explanation

['^(##?#?) (.+)'[\#'5\-@k CS k*k rep LF#`]3/mrepl]
[                                            mrepl]   perform multiline replacement
 '^(##?#?) (.+)'                                     regex matching headers
                [                        ]3/         on each match:
                 \#'                                   count number of hashes
                    5\-                                5 - (^)
                       @k                              set k to number of repetitions
                          CS                           convert the header to a char string
                             k*                        repeat each char `k` times
                               k rep                   repeat said string `k` times
                                     LF#`              join by linefeeds
\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 111 105 bytes

Saved 6 bytes thanks to @Shaggy

s=>s.replace(/^(##?#?) (.+)/gm,(_,a,b)=>`
${b.replace(/./g,e=>e.repeat(l=5-a.length))}`.repeat(l).trim())

Matches 1-3 hashes at the beginning of the string or preceded by a new line, then repeats each character in the match along with the match itself, based on the length of the hashes.

Test Cases:

let f=

s=>s.replace(/^(##?#?) (.+)/gm,(_,a,b)=>`
${b.replace(/./g,e=>e.repeat(l=5-a.length))}`.repeat(l).trim())

console.log(f('# This is a text\nwith two different\n### headers!'));
console.log('______________________________________________');
console.log(f('This input has\n## trailing hash marks ##\n#and a hash mark without a space after it.'));
console.log('______________________________________________');
console.log(f('# This ## is ### strange\n#### ###'));
console.log('______________________________________________');
console.log(f('Multiple\n\n\n### newlines! # \n:)'));
console.log('______________________________________________');
console.log(f('Line with only a hash mark:\n#\n### ^ Like that!'));

\$\endgroup\$
2
\$\begingroup\$

Retina, 125 104 bytes

m(`(?<=^# .*).
$0$0$0$0
(?<=^## .*).
$0$0$0
(?<=^### .*).
$0$0
^# 
$%'¶$%'¶$%'¶
^## 
$%'¶$%'¶
^### 
$%'¶

Try it online

Saved 21 bytes thanks to Neil.

\$\endgroup\$
  • \$\begingroup\$ Save 3 bytes by using %) on the third stage which allows you to remove the %s on the first two stages. Also one normally puts the G after the (s (of which you'll now need two) in the header. \$\endgroup\$ – Neil Nov 17 '17 at 2:02
  • \$\begingroup\$ Better still, you can use m) or m( which now saves 9 bytes because you can then remove all of the other ms. \$\endgroup\$ – Neil Nov 17 '17 at 2:04
  • \$\begingroup\$ The header turned out to be unnecessary. Also, I saved another 12 bytes: Try it online! \$\endgroup\$ – Neil Nov 17 '17 at 2:09
  • \$\begingroup\$ Oh, yeah I was just used to using the header for multiple test cases. \$\endgroup\$ – mbomb007 Nov 17 '17 at 4:14
2
\$\begingroup\$

MATL, 43 42 40 bytes

1 byte removed thanks to Rick Hitchcock!

`j[]y'^##?#? 'XXgn:(2M4:QP&mt~+t&Y"0YcDT

This outputs a trailing space in each line (allowed by the challenge), and exits with an error (allowed by default) after producing the ouput.

Try it online!

Explanation

`            % Do...while loop
  j          %   Input a line as unevaluated string
  []         %   Push empty array
  y          %   Duplicate from below: push input line again
  '^##?#? '  %   Push string for regexp pattern
  XX         %   Regexp. Returns cell array with the matched substrings
  g          %   Get cell array contents: a string, possibly empty
  n          %   Length, say k. This is the title level plus 1, or 0 if no title
  :(         %   Assign the empty array to the first k entries in the input line
             %   This removing those entries from the input
  2M         %   Push k again
  4:QP       %   [1 2 3 4], add 1 , flip: pushes [5 4 3 2]
  &m         %   Push index of k in that array, or 0 if not present. This gives
             %   4 for k=2 (title level 1), 3 for k=3 (tile level 2), 2 for k=2
             %   (title level 1), and 0 for k=0 (no title). The entry 5 in the
             %   array is only used as placeholder to get the desired result.
  t~+        %   Duplicate, negate, add. This transforms 0 into 1
  t&Y"       %   Repeat each character that many times in the two dimensions
  0Yc        %   Postpend a column of char 0 (displayed as space). This is 
             %   needed in case the input line was empty, as MATL doesn't
             %   display empty lines
  D          %   Display now. This is needed because the program will end with
             %   an error, and so implicit display won't apply
  T          %   True. This is used as loop condition, to make the loop infinite
             % End (implicit)
\$\endgroup\$
  • \$\begingroup\$ I was wondering what the best way to do this in MATLAB was... Kronecker product was of course the best way to do it :) Nice! \$\endgroup\$ – Stewie Griffin Nov 17 '17 at 10:04
  • \$\begingroup\$ @StewieGriffin When I saw the challenge I immediately thought of Kronecker product. But I just found a way that is 2 bytes shorter using repelem (Y" in MATL). kron is still probably the shortest way in MATLAB \$\endgroup\$ – Luis Mendo Nov 17 '17 at 10:10
2
\$\begingroup\$

Perl 5, 47 +1 (-p) bytes

s/^##?#? //;$.=6-("@+"||5);$_=s/./$&x$./ger x$.

try it online

\$\endgroup\$
1
\$\begingroup\$

Charcoal, 46 bytes

FN«Sι≔⊕⌕E³…⁺×#κι⁴### θF⎇θ✂ι⁻⁵θLι¹ι«G↓→↑⊕θκ→»D⎚

Try it online! Link is to verbose version of code. Charcoal doesn't really do string array input, so I've had to add the array length as an input. Explanation:

FN«Sι

Loop over the appropriate number of input strings.

≔⊕⌕E³…⁺×#κι⁴### θ

Create an array of strings by taking the input and prefixing up to 2 #s, then truncating to length 4, then try to find ### in the array, then convert to 1-indexing. This results in a number which is one less than the letter zoom.

F⎇θ✂ι⁻⁵θLι¹ι«

If the letter zoom is 1 then loop over the entire string otherwise loop over the appropriate suffix (which is unreasonably hard to extract in Charcoal).

G↓→↑⊕θκ→

Draw a polygon filled with the letter ending at the top right corner, and then move right ready for the next letter.

»D⎚

Print the output and reset ready for the next input string.

\$\endgroup\$
1
\$\begingroup\$

SOGL V0.12, 31 28 bytes

¶Θ{■^##?#? øβlF⁄κ6κ5%:GI*∑∙P

Try it Here! - extra code added because the code is a function and takes input on stack (SOGL can't take multiline input otherwise :/) - inputs.value” - push that string, - evaluate as JS, F - call that function

Explanation:

¶Θ                            split on newlines
  {                           for each item
   ■^##?#?                      push "^##?#? "
           øβ                   replace that as regex with nothing
             l                  get the new strings length
              F⁄                get the original strings length
                κ               and subtract from the original length the new strings length
                 6κ             from 6 subtract that
                   5%           and modulo that by 5 - `6κ5%` together transforms 0;2;3;4 - the match length to 1;4;3;2 - the size
                     :          duplicate that number
                      G         and get the modified string ontop
                       I        rotate it clockwise - e.g. "hello" -> [["h"],["e"],["l"],["l"],["o"]]
                        *       multiply horizontally by one copy of the size numbers - e.g. 2: [["hh"],["ee"],["ll"],["ll"],["oo"]]
                         ∑      join that array together - "hheelllloo"
                          ∙     and multiply vertiaclly by the other copy of the size number: ["hheelllloo","hheelllloo"]
                           P    print, implicitly joining by newlines
\$\endgroup\$
0
\$\begingroup\$

Proton, 130 bytes

x=>for l:x.split("\n"){L=l.find(" ")print(L>3or L+len(l.lstrip("\#"))-len(l)?l:"\n".join(["".join(c*(5-L)for c:l[L+1to])]*(5-L)))}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I think you are not allowed to receive and return a list of lines, the rules are quite strict: You must support input over multiple lines., The output must be presented over multiple lines. You may not output \n instead of literal newlines.. \$\endgroup\$ – Mr. Xcoder Nov 16 '17 at 21:17
  • \$\begingroup\$ @Mr.Xcoder Whoops, my bad. Fixing. \$\endgroup\$ – HyperNeutrino Nov 16 '17 at 21:19
  • \$\begingroup\$ Note: It's OK if the input has \n, but the output should be shown with literal newlines. \$\endgroup\$ – Stewie Griffin Nov 16 '17 at 21:31
  • \$\begingroup\$ @mbomb007 Whoops I forgot to put the 5- in there. Sorry \$\endgroup\$ – HyperNeutrino Nov 16 '17 at 21:40
  • \$\begingroup\$ @mbomb007 fixed \$\endgroup\$ – HyperNeutrino Nov 16 '17 at 22:22
0
\$\begingroup\$

Python 3, 147 bytes

def f(x):
	for l in x.split("\n"):L=l.find(" ");print(L>3or L+len(l.lstrip("#"))-len(l)and l or"\n".join(["".join(c*(5-L)for c in l[L+1:])]*(5-L)))

Try it online!

-1 byte thanks to Mr. Xcoder

\$\endgroup\$
  • \$\begingroup\$ @mbomb007 Whoops I forgot to put the 5- in there. Sorry \$\endgroup\$ – HyperNeutrino Nov 16 '17 at 21:40
0
\$\begingroup\$

C# (.NET Core), 268 + 18 bytes

n=>{var r="";for(int l=0,c;l<n.Length;l++){var m=n[l];var s=m.Split(' ');var y=s[0];if(!y.All(x=>x==35)|y.Length>3|s.Length<2)r+=m+'\n';else for(int i=0,k=y.Length;i<5-k;i++){for(c=1;c<m.Length-k;)r+=new string(m.Substring(k,m.Length-k)[c++],5-k);r+='\n';}}return r;};

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Python 3, 131 bytes

from re import*
print(sub("^(#+) (.*?)$",lambda x:((sub('(.)',r'\1'*(5-len(x[1])),x[2])+'\n')*(5-len(x[1])))[:-1],input(),flags=M))

Try it online!

I used Python 3 in order to use [] with regex.

\$\endgroup\$
0
\$\begingroup\$

PHP, 122+1 bytes

for($y=$z=" "==$s[$i=strspn($s=$argn,"#")]&&$i?5-$i++:1+$i=0;$y--;print"
")for($k=$i;~$c=$s[$k++];)echo str_pad($c,$z,$c);

Run as pipe with -nR (will work on one input line after another) or try it online.

\$\endgroup\$
0
\$\begingroup\$

J, 55 bytes

([:{:@,'^##?#? 'rxmatch])((1 1 4 3 2{~[)([:|:[$"0#)}.)]

I don't know how to make TIO work with J regex, so I can't provide a working link.

Here's how to test it in the J interpreter (tested with J804)

   f=.([:{:@,'^##?#? 'rxmatch])((1 1 4 3 2{~[)([:|:[$"0#)}.)]
   txt=.'# Hello'; '## A B C def'; '### PPCG!'; '#and a hash mark without a space after it.'; '##### ###'
   ; f each txt

HHHHeeeelllllllloooo                      
HHHHeeeelllllllloooo                      
HHHHeeeelllllllloooo                      
HHHHeeeelllllllloooo                      
AAA   BBB   CCC   dddeeefff               
AAA   BBB   CCC   dddeeefff               
AAA   BBB   CCC   dddeeefff               
PPPPCCGG!!                                
PPPPCCGG!!                                
#and a hash mark without a space after it.
##### ###

I simulate a multiline string through a list of boxed strings.

\$\endgroup\$
0
\$\begingroup\$

Python 2, 126 124 117 bytes

while 1:l=raw_input();i=l.find(' ');v=5-i*(l[:i]in'###');exec"print[l,''.join(c*v for c in l[i+1:])][v<5];"*(v>4or v)

Try it online!

or

while 1:l=raw_input();i=l.find(' ');t=''<l[:i]in'###';exec"print[l,''.join(c*(5-i)for c in l[i+1:])][t];"*(t<1or 5-i)

Try it online!

\$\endgroup\$
0
\$\begingroup\$

JavaScript, 112 bytes

x=>x.replace(/^(##?#?) (.*)/mg,(_,n,w)=>(t=>Array(t).fill(w.replace(/./g,c=>c.repeat(t))).join`
`)(5-n.length))

f=

x=>x.replace(/^(##?#?) (.*)/mg,(_,n,w)=>(t=>Array(t).fill(w.replace(/./g,c=>c.repeat(t))).join`
`)(5-n.length))
<textarea id=i style=display:block oninput=o.value=f(i.value)></textarea>
<output id=o style=display:block;white-space:pre></output>

\$\endgroup\$
  • \$\begingroup\$ I don't think this works for #### ##. \$\endgroup\$ – Rick Hitchcock Nov 17 '17 at 14:20
  • \$\begingroup\$ @RickHitchcock fixed \$\endgroup\$ – tsh Nov 18 '17 at 8:35
0
\$\begingroup\$

C# 4.5 158 Bytes

Where i is the input in the form of a string.

int l,m,t,s=0;while(i[s]=='#'){s++;};t=s>0?4-s+1:1;for(l=0;l<t;l++){foreach(char c in i.Skip(s>0?s+1:0))for(m=0;m<t;m++)Console.Write(c);Console.WriteLine();}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.