# Surround a string with hashes

I've already made this in Python, but it seems that it could be shortened a lot:

txt = input("Type something.. ")
c = "#"
b = " "
print(c * (len(txt) + 4))
print(c, b * len(txt), c)
print(c, txt, c)
print(c, b * len(txt), c)
print(c * (len(txt) + 4))


So if the user types:

Hello World


The program prints:

###############
#             #
# Hello World #
#             #
###############


Fewest bytes wins—and of course, the answer can be written in any language.

• The same challenge as editor golf. Sep 13 '15 at 12:44
• Not so different: codegolf.stackexchange.com/questions/57442/show-tree-rings-age/… Sep 13 '15 at 13:40
• The input string won't contain linebreaks, right? Sep 13 '15 at 13:51
• @edc65 I disagree, this challenge is hugely different Sep 13 '15 at 13:55
• I would recommend to wait at least a week before accepting an answer. While it doesn't really matter if you are planning to update the accepted answer if a shorter submission comes in, there will be people complaining about an early accepted answer, or even downvote it. There will also be some people who won't be interested in posting an answer if there is already an accepted one. Sep 13 '15 at 17:36

# CJam, 22 20 bytes

qa{4/3*' +f+W%z}8/N*


Test it here.

## Explanation

How do you wrap a 2D grid of characters in one layer of spaces (or any other character)? Correct: four times, you append a space to each line and then rotate the grid by 90 degrees. That's exactly what I'm doing here with eight rotations: four for spaces, four for #:

qa      e# Read the input and wrap it in an array, to make it a 2D grid.
{       e# Execute this block for each value from 0 to 7.
4/3*  e#   Divide by 4, multiply by 3. Gives 0 for the first four iterations and
e#   and 3 for the other four.
' +   e#   Add the result to a space character (space + 3 == #).
f+    e#   Append this to each line of the grid.
W%z   e#   Reverse the lines, then transpose the grid - together these rotate it.
}8/
N*      e# Join the lines of the grid by newlines.

• What a neat solution! Sep 13 '15 at 19:26
• I love the explanation :-D Sep 13 '15 at 20:01

## vim, 28 27 keystrokes

I# <esc>A #<esc>Y4PVr#G.kwv$3hr kk.  Assumes input is provided as a single line of text in the currently open file. Explanation: I# <esc> put a "#" and space at the beginning of the line A #<esc> put a space and "#" at the end of the line Y4P copy the line 4 times Vr# replace the entirety of the first line with "#"s G. do the same for the last line kwv$3hr<space>  replace middle of the fourth line with spaces
kk.             do the same for the second line


This can also be run as a "program" like so:

echo 'Hello World' | vim - '+exe "norm I# \<esc>A #\<esc>Y4PVr#G.kwv$3hr kk."'  Which is a bit convoluted, but it works. • This is the best answer, because it works like my mind does. Sep 14 '15 at 0:44 # pb - 89 bytes vw[Y!-1]{b^}w[B!0]{t[B]vvv>>b[T]^^^<}v>>>w[Y!4]{bv}w[X!0]{b^[Y]bv<}  This is the kind of challenge pb was made for! Not that it's competitive for this kind of challenge or anything. It's still a horrible golf language. However, challenges like this are a lot less of a pain to solve in pb than others are. Since pb treats its output as a 2D canvas and is able to write to any coords, anything involving positioning text/drawing around text (i.e. this challenge) is handled rather intuitively. Watch it run: This visualization was created with an in-development version of pbi, the pb interpreter. The line with the blue background is Y=-1, where input is stored when the program starts. The rectangle with the red background is the current location of the brush. The rectangles with yellow backgrounds are anywhere the ascii character 32 (a space) is explicitly written to the canvas. Any blank spaces without this background actually have the value 0, which is converted to a space. Here's the code with the comments I used while writing it, with some thematically relevant section headers ;) ################################ # # # Handle first column oddities # # # ################################ v # Start from Y=4 and go up (so we land on input afterwords) w[Y!-1]{ # While we're on the visible part of the canvas b^ # Write "#", then go up } ######################### # # # Insert text of output # # # ######################### w[B!0]{ # For each character of input t[B] # Save input char in T vvv>> # Down 3 + right 2 = where text part of output goes b[T]^^^< # Write T and go to next char } ############################### # # # Handle last column oddities # # # ############################### v>>> # Go to Y=0, X=(X of last text output's location + 2) w[Y!4]{ # Until we reach the last line of output bv # Draw "#", then go down } ########################### # # # Loop to finish Y=0, Y=4 # # # ########################### w[X!0]{ # Until we've gone all the way left b^[Y] # Print "#" at Y=4, go to Y=0 bv # Print "#" at Y=0, go to Y=4 < # Move left, printing until output is complete }  • Not that it's competitive... It's still a horrible golf language. I say that, but right now I'm only tied for last. I was expecting to be last outright. :D Sep 13 '15 at 16:48 # brainfuck - 156 bytes ++++++++++>,[>>+++++[<+++++++>-],]<....[.---<<]>>+++>>+++.---.[.>>]<<.+++.[<]>.>>+++.---.<[.>>]<<<.>>.---[<]>.--->>+++.---[.>>]<<..+++.---[<]>[+++.>>]<<....  This is probably golfable. There's some places where I didn't know if it would be better to store a value somewhere for reuse or to remake it/go get it from elsewhere on the tape. Instead of doing the work to figure it out, I didn't do that. :D With comments: ++++++++++> Place a 10 (\n) at the beginning of the tape ,[>>+++++[<+++++++>-],] Place a byte of input; place a 35 (#); repeat until end of input <.... Print the last cell (35; #) 4 times [.---<<] Print every noninput cell on the tape in reverse (one # for each byte of input; then \n) After printing each cell; decrease it by 32 >>+++ Increase the 7 back up to 10 >>+++.---. Increase a 32 (space) back up to 35 (#); print it; put it back to 32 and print again [.>>] Print every 32 on the tape (one for each byte of input) <<.+++. Print the last space again; increase it by 3 and print the resulting # [<]>. Go to the beginning of the tape and print the \n >>+++.---. Increase a 32 (space) back up to 35 (#); print it; put it back to 32 and print again <[.>>] Print every byte of input <<<.>>.--- Print a space; then print a 35 (#} that was left behind earlier; Set it back to 32 after [<]>.--- Go to the beginning of the tape and print the \n; decrease by 3 >>+++.--- Set a space to #; print it; set it back to space [.>>] Print all spaces <<..+++.--- Print a space twice more; set it to #; print it again; set it back to space [<]> Go to the "newline" (currently a 7 instead of 10) [+++.>>] Increase by 3; print; do the same for all spaces (to set them to # before printing) <<.... Print the last # 4 more times  # K, 21 bytes 4(|+"#",)/4(|+" ",)/,  Enlist the string, Add a space to all four sides of a string, then add an octothorpe to each side of the string. In action:  4(|+"#",)/4(|+" ",)/,"Hello." ("##########" "# #" "# Hello. #" "# #" "##########")  Works in oK, Kona and k5. There are quite a few variations within one character of length which remove the redundancy in the above, but none seem to break even when we only have to perform the "wrap" operation twice: {x{|+x," #"y}/&4 4},: {x{|+x,y}/,/4#'" #"},: {x{|+x,y}/" #"@&4 4},: {|+x,y}/[;" #"@&4 4],:  # Python 3, 88 bytes Thanks @WorldSEnder s=" ";n=s+input()+s b=len(n) h="#";x=h*(b+2);y=h+s*b+h;z="\n" print(x+z+y+z+h+n+h+z+y+z+x)  ## Example I/O: This is a test ################## # # # This is a test # # # ##################  • s=" " at the beginning saves 1 byte overall I think. Sep 13 '15 at 18:53 • Why using ; instead of new lines btw? Both should be one byte, right? Sep 13 '15 at 21:56 • @JeromeJ I know it doesn't make a difference, but it looks shorter if you put it on one line ;) Sep 14 '15 at 5:53 • 72 bytes Aug 11 '20 at 21:23 # Python 2, 67 bytes s=input() n=len(s)+2 y='#\n#' x='#'*-~n+y+' '*n+y print x,s,x[::-1]  Try it online! # Pyth, 31 bytes Js[K\#*d+2lzKb*K+4lz)_Jjd[KzK)J  Thanks to people in comments giving hints on how to golf further, I really don't know the language well as you can (probably) tell. • Couple of hints: "#" is equal to \#. If you have to concatenate a lot of objects you're better of using j""[ followed by a list of objects, which is equal to jk[. – orlp Sep 13 '15 at 13:24 • Some more hints. s[ is equal to jk[ for arrays of strings. Also, you can also assign K on the fly, like jk[K\#, and just drop the initial assign. Assigning lz to J doesn't help if only used twice, so save J for something else. Here, if you swap Z for J you can remove the =. Finally, you can assign J on the fly. The code then looks like this: _Js[K\#*d+2lzKb*K+4lz)jd[KzK)J Sep 13 '15 at 16:56 # Perl, 43 76 bytes Transform each text input line as specified: s/.*/($x=("#"x(4+($z=length))))."\n".($y="#"." "x(2+$z)."#\n")."#$& #\n$y$x"/e


For example:

echo surround a long string with pounds |
perl -ple's/.*/($x=("#"x(4+($z=length))))."\n".($y="#"." "x(2+$z)."#\n")."# $& #\n$y$x"/e' ###################################### # # # surround a long string with pounds # # # ######################################  Here’s how to see what it’s really doing: perl -MO=Deparse,-p,-q,-x9 -ple '($x=("#"x(4+($z=length))))."\n".($y="#"." "x(2+$z)."#\n")."#$& #\n$y$x";'
BEGIN { $/ = "\n";$\ = "\n"; }
LINE: while (defined(($_ = <ARGV>))) { chomp($_);
(((($x = ('#' x (4 + ($z = length($_))))) . "\n") . ($y = (('#' . (' ' x (2 + $z))) . "#\n"))) . (((('# ' .$&) . " #\n") . $y) .$x));
}
continue {
(print($_) or die((('-p destination: ' .$!) . "\n")));
}
-e syntax OK


So something more like this:

((
(($x = ('#' x (4 + ($z = length($_))))) . "\n") . ($y = (('#' . (' ' x (2 + $z))) . "#\n")) ) . (((('# ' .$&) . " #\n") . $y) .$x)
)

• There should be a row of white space padding before and after the string. Take a look at the example output from the question.... but nice to see you submitting... especially in Perl :D Sep 13 '15 at 23:52
• @rayryeng It made me sad that nobody was submitting in Perl. Sep 13 '15 at 23:55
• To be honest I was surprised. This certainly seems like a problem suited for it :). Sep 13 '15 at 23:56
• @rayryeng Fixed in the next release. :) Sep 14 '15 at 0:31
• Actually, now that I think about it, if you split everything into separate statements, you can simply move them outside the substitution and drop the e modifier...but if you do that, you might as well just drop the substitution altogether: $x="#"x(4+($z=y!!!c));$y="#".$"x(2+$z)."#\n";$_="$x\n$y# $_ #\n$y$x". Use actual newlines instead of \n and it's only 65 bytes, plus 2 for -lp. Sep 16 '15 at 18:26 # Perl 5.14+, 57 56 bytes perl -lpe '$_=join"#
#",($_="$_ ",y// /cr,"#".y//#/cr)[2,1,0..2]'


54 bytes + 2 bytes for -lp (if input doesn't end in a newline, -l can be dropped to save one byte).

Accepts input on STDIN:

$echo Hello World | perl -lpe '$_=join"#
#",($_="$_ ",y// /cr,"#".y//#/cr)[2,1,0..2]'
###############
#             #
# Hello World #
#             #
###############


## How it works

The core of the program is a list slice:

($_="$_ ",y// /cr,"#".y//#/cr)[2,1,0..2]'


This provides a compact way to store the three unique rows of the output (the first two rows of the bounding box are the same as the last two, only mirrored). For the input string foo, the results of the slice would be:

index   value
--------------
2    "######"
1    "     "
0    " foo "
1    "     "
2    "######"


Joining these values with #\n# gives us our box.

Note that Perl 5.14+ is required to use the non-destructive r modifier to the transliteration operator y///.

# JavaScript (ES6), 73

Heavily using template string, the 2 newlines are significant and counted.

Test running the snippet below in any EcmaScript 6 compliant browser (FireFox and latest Chrome, maybe Safari).

f=s=>(z=c=>*${c.repeat(s.length+2)}* )*+z +*${s} *
+z +z*

// Less golfed

U=s=>(
z=c=>'*' + c.repeat(s.length+2) + '*\n',
z('*') + z(' ') + '* ' + s + ' *\n' + z(' ') + z('*')
)

// TEST

O.innerHTML=f('Hello world!')
<pre id=O></pre>

This is quite shorter than my first try, derived from this other challenge:

f=s=>(q=(c,b,z=c.repeat(b.length))=>[z,...b,z].map(r=>c+r+c))('*',q(' ',[s])).join\n

• Doesn't run for me (Canary).
– user42643
Sep 13 '15 at 15:05
• @minxomat what is Canary? Sep 13 '15 at 15:10
• It works in Chrome 45.0.2454.85 m, Windows 7 Sep 13 '15 at 15:12
• Canary is always the latest Chrome build. Doesn't work in my Chrome Stable either. Edit: Works in FireFox though.
– user42643
Sep 13 '15 at 15:15
• (Is it legal to assign to the global z as a side-effect?)
– Neil
Sep 13 '15 at 20:53

## Python 2, 74

s='# %s #'%input()
n=len(s)
b='\n#'+' '*(n-2)+'#\n'
print'#'*n+b+s+b+'#'*n


Takes input in quotes like "Hello World".

• The third line is the input encased in # _ #.
• The second and fourth lines b are # # with the right number of spaces, surrounded with newlines to either side to take care of all four newlines.
• The first and fifth lines are # multiplied to the length of the input

The lines are concatenated and printed.

# MATLAB, 93 91 bytes

Not the prettiest, but it gets the job done.

t=[32 input('','s') 32];m='#####'.';n=repmat('# ',numel(t),1)';disp([m [n;t;flipud(n)] m])


# Code Explanation

## Step #1

t=[32 input('','s') 32];


Read in a string from STDIN and place a leading and trailing single space inside it. 32 is the ASCII code for a space and reading in the input as a string type coalesces the 32s into spaces.

## Step #2

m='#####'.';


Declare a character array of 5 hash signs in a column vector.

## Step #3

n=repmat('# ',numel(t),1)'


Create a 2 row character matrix that is filled by hash signs first followed by white space after. The number of characters is the length of the input string plus 2 so that we can accommodate for the space before and after the string.

## Step #4

disp([m [n;t;flipud(n)] m])


We're going to piece everything together. We place the first column of 5 hashes, followed by the centre portion and followed by another column of 5 hashes. The centre portion consists of the 2 row character matrix created in Step #3, the input string itself which has a trailing and leading space, followed by the 2 row character matrix but reversed.

# Example Runs

>> t=[32 input('','s') 32];m='#####'.';n=repmat('# ',numel(t),1)';disp([m [n;t;flipud(n)] m])
This is something special for you
#####################################
#                                   #
# This is something special for you #
#                                   #
#####################################
>> t=[32 input('','s') 32];m='#####'.';n=repmat('# ',numel(t),1)';disp([m [n;t;flipud(n)] m])
Hello World
###############
#             #
# Hello World #
#             #
###############
>> t=[32 input('','s') 32];m='#####'.';n=repmat('# ',numel(t),1)';disp([m [n;t;flipud(n)] m])
I <3 Code Golf StackExchange!
#################################
#                               #
# I <3 Code Golf StackExchange! #
#                               #
#################################


## Pyke (noncompetitive), 6 bytes

.X".X#


Try it here!

Pyke was written after the challenge and is therefore noncompetitive.

.X"    - surround string in spaces
.X# - surround string in hashes


.X takes a string and a string constant arg and surrounds a string with that group of characters. The constant arg can be up to 8 characters and have different effects on how the string is surrounded.

# PHP, 95 93 bytes

Not exactly brilliant or anything similar, but it was actually fun!

$l=strlen($s=" $argv ");printf("#%'#{$l}s#

# PHP, 93 91 bytes

$b=str_pad("",$e=strlen($s="$argv "));echo$h=str_pad("",2+$e,"#"),"
#$b# #$s#
#$b#$h";


Takes input from command line argument; escape spaces or use single quotes. Run with -r.

## C# - 142 bytes (method body is 104)

class P{static void Main(string[]a){for(int i=0;++i<6;)System.Console.Write("#{0}#\n",i==3?$" {a} ":new string(" #"[i%2],a.Length+2));}}  Ungolfed: class P { static void Main(string[] a) { for (int i = 0; ++i < 6;) System.Console.Write("#{0}#\n", i == 3 ?$" {a} " : new string(" #"[i%2], a.Length + 2));
}
}


x a=(\s->s++a++reverse s)$concat["##",'#'<$a,"##\n# ",' '<$a," #\n# "]  Try it online! # Haskell, 68 bytes x a=id<>pure a<>reverse$concat["##",'#'<$a,"##\n# ",' '<$a," #\n# "]


Try it online! (Doesn't work since TIO uses an old GHC where <> isn't imported by default.)

x a|s<-['#'<$a,"####\n# ",' '<$a," #\n# "]>>=id=s++a++reverse s


Try it online!

• You should use a pattern guard rather than a lambda for your binding. Aug 7 '20 at 20:06
• Also >>=id is usually shorter than concat. Aug 7 '20 at 20:07
• Good ideas! Also combined two of the string literals. Aug 7 '20 at 20:12
• I spent a little longer with this and came up with a 57 byte variation that abuses do notation to get a slight advantage. Aug 7 '20 at 20:24

map{say"#$_#"}($_=" $_ ",y// /cr,y//#/cr)[2,1,0..2]  Try it online! # MAWP, 108 bytes %|_4M[75W;1A]%52W;75W;84W;_1M[84W;1A]%75W;25W;75W;84W;0__~[;]%84W;75W;52W;75W;1M![84W;1A]%75W;52W;2M[75W;1A]  Try it! Now an actually valid solution Explanation: % Remove the 1 already on stack | Push input as ascii _4M Push length of stack + 4 [75W;1A]% Print that many # 52W; Print a newline 75W; Print # 84W; Print a space _1M Push length of stack + 1 [84W;1A]% Print that many spaces 75W;25W; Print # with a newline 75W;84W; Print # with a space 0 Push a 0 __ Push length of stack twice ~[;] Reverse stack and print until 0 % Remove top of stack 84W;75W;52W; Print a space, # and newline 75W; Print # 1M! Add 1 to top and duplicate it [84W;1A]% Print that many spaces 75W;52W; Print # with a newline 2M[75W;1A] Add 2 and print that many #  • The second and fourth lines should have two hashes separated by length+2 spaces. Aug 11 '20 at 6:32 • @Razetime welp... i knew something was wrong with it. facepalm – Dion Aug 11 '20 at 6:53 • @Razetime now should be valid. Also, i noticed you were using ascii(13) for newlines instead of 10. Am i missing out on something? Aren't newlines ascii(10) be valid as well? – Dion Aug 11 '20 at 7:29 • I just started golfing a week ago, so I still have a lot to learn, haha. I don't think there's any rule about that. Aug 11 '20 at 7:40 • @Razetime you're doing great for the first week, way better than i did! Also, thanks for all the help with the interpreter, as this is my first actual project in javscript/html/css :) – Dion Aug 11 '20 at 7:48 # R, 106 95 bytes function(t,l=nchar(t),n="# #",s=" ",&=strrep)cat(a<-"#"&l+3,b<-c(n,s&l+2,n),s,t,s,b,a,sep="")  Try it online! -5 bytes thanks to @Dominic, which led to further golfs. • 101 bytes... May 11 at 9:57 # Python 3, 82 bytes d,h,s,m=input(),'#',' ','\n' l=len(d)+2 print(l*h+h,l*s,s+d+s,l*s,l*h+h,sep=h+m+h)  Try it online! • Welcome to CGCC! Your code actually only has 82 bytes. I've added a Try It Online link as well, which just lets people test / verify your code a bit more easily. Good first answer! May 11 at 19:35 # 05AB1E (legacy), 20 bytes g4+'#×©,¹' .ø'#.ø,®,  Try it online! # Vyxalj, 29 bytes L4+\#*:\#?L½›꘍m:„W2\#ð+Ḃ?$++Ṁ


Try it Online!

For some reason Vertical mirror and center doesn't work

# Python 3, 68 bytes

s=input()
n=len(s)+2
v='#'*n+'##\n#'+' '*n+'#\n#'
print(v,s,v[::-1])


Try it online!