g | x | w | all
Bytes Lang Time Link
034Regenerate210627T004215ZDLosc
077AWK250828T211943Zxrs
053Ruby nl230731T214741ZValue In
145><>230731T172817Zjoyofori
014Vyxal j230730T134044Zlyxal
016Thunno 2 N230730T080156ZThe Thon
014Stax211020T222436Zrecursiv
019APL Dyalog Unicode211020T141240Zovs
121Java JDK211020T133625Z0xff
068Python 3210628T104516ZHunaphu
017Japt h210628T091137ZShaggy
029Vyxal j210628T023355Zwasif
02005AB1E legacy161009T192834ZLuke
082Python 3210511T193208Zdrmosley
095R210510T124802Zpajonk
021J210510T034752ZJonah
067Python 2210510T033743Zdingledo
107MAWP200807T131157ZRazetime
108MAWP200811T061026ZDion
051Perl 5 n200807T212135ZXcali
070Haskell200807T185138ZKyuuhach
066Python 3200807T155225ZKyuuhach
073SmileBASIC170202T034507Z12Me21
165C gcc170202T075542ZAbel Tom
142C#161030T235845ZOzzieret
093PHP150913T221327ZIsmael M
110C#161008T223041Zadrianmp
172Racket161009T011338Zrnso
006Pyke noncompetitive161008T190208ZBlue
091PHP161008T145020ZTitus
056Perl 5.14+150915T070506ZThisSuit
083Ruby150914T191451Zjmm
090Lua150914T042630ZTrebuche
091MATLAB150913T231751Zrayryeng
076Perl150913T233106Ztchrist
104><>150913T212845Zcole
198C++150913T230151ZCyv
082PowerShell150913T223500Zbriantis
020CJam150913T133216ZMartin E
074Python 2150913T193727Zxnor
088Python 3150913T130453ZBeta Dec
027vim150913T153242ZDoorknob
156brainfuck150913T174227Zundergro
031Pyth150913T131843ZBlue
089pb150913T161340Zundergro
021K150913T145601ZJohnE
073JavaScript ES6150913T143812Zedc65

Regenerate, 38 34 bytes

(#{#~1+4})(
# {#1-2}#
)# $~1 #$2$1

Takes the string as a command-line argument. Attempt This Online!

Explanation

Spaces are replaced by underscores and newlines by ¶ so they're easier to see.

(        )                          Group 1: top row
 #                                   Hash character
  {     }                            repeated
   #~1                               len(input)
      +4                             + 4 times
          (           )             Group 2: second row (plus newlines)
           ¶#                        Newline followed by hash
             _{    }                 followed by space repeated
               #1-2                  len(group 1) - 2 times
                    #¶               followed by hash and another newline
                                    Middle row:
                       #_            Hash followed by space
                         $~1         followed by input
                            _#       followed by space and another hash
                                    Final two rows:
                              $2     Group 2 again
                                $1   Group 1 again

AWK, 77 bytes

{for(a=b=c="#";i++<length+2;c=c" ")a=a b}$0=a (c=b RS c b RS) b FS$0 FS c a b

Attempt This Online!

Ruby -nl, 53 bytes

s="# %s #"
puts h=?#*(4+l= ~/$/),s%b=' '*l,s%$_,s%b,h

Attempt This Online!

><>, 145 bytes

i:0(?v
[1+2l57*o1
*o:&v>]~]ao57
2(?v>84*o1-:
aov>~~57*o
rv>84*:57*:@oo$
o>l3(?v
o57*ov>roo&:1[a
:2(?v>84*o1-
oaov>]~75*
(?;>57*o1-:0

Probably very overcomplicated but it works and is kind of short. Just gotta love ><>.

The code prints the output line by line. Every line has at least two lines responsible for it. One to print and the to "clean up" after the first line, deleting useless garbage in the stack, printing newlines, registering the register, etc.

Try it here
(This was the hardest golf I've done)

Vyxal j, 112 bitsv2, 14 bytes

L⇧‛# •½pøĊ\#vø.∞

Try it Online!

I know I said I love parallel apply, but I didn't actually need it here lol.

Explained

L⇧‛# •½pøĊ\#vø.∞­⁡​‎‎⁡⁠⁣‏⁠‎⁡⁠⁤‏⁠‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁢⁣‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁢⁤‏‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁣⁡‏⁠‎⁡⁠⁣⁢‏‏​⁡⁠⁡‌⁢⁢​‎‎⁡⁠⁣⁣‏⁠‎⁡⁠⁣⁤‏⁠‎⁡⁠⁤⁡‏⁠‎⁡⁠⁤⁢‏⁠‎⁡⁠⁤⁣‏‏​⁡⁠⁡‌⁢⁣​‎‎⁡⁠⁤⁤‏‏​⁡⁠⁡‌⁢⁤​‎‏​⁢⁠⁡‌­
  ‛# •            # ‎⁡Repeat each character in the string "# "
L⇧                # ‎⁢(len input) + 2 times
      ½           # ‎⁣Split into two halves - a string of #s and spaces
       p          # ‎⁤Prepend the input
        øĊ        # ‎⁢⁡And horizontally centre so that the input has enough spacing on both sides
          \#vø.   # ‎⁢⁢Prepend and append "#" to each string
               ∞  # ‎⁢⁣And mirror it, not mirroring the centre item
# ‎⁢⁤The j flag joins on newlines
💎

Created with the help of Luminespire.

Thunno 2 N, 16 bytes

ðṛ[l'#×;lṣ;]'#ṛⱮ

Try it online!

Explanation

ðṛ[l'#×;lṣ;]'#ṛⱮ  # Implicit input
ðṛ                # Surround by spaces
  [    ;  ;]      # Apply parallelly, and wrap into a list:
   l'#×          '#   [0]  length * "#"
        lṣ        #   [1]  length * " "
                  #   [2]  leave TOS
            '#ṛ  '# Surround each by "#"s
               Ɱ  # Palindromise the list

Stax, 14 bytes

≡┼ö▓ú¡êqct╜R"Γ

Run and debug it

APL (Dyalog Unicode), 19 bytes

(⍉⍪⍪⊣)/'##  ',⊂∘⍉∘⍪

Try it online!

Java (JDK), 121 bytes

i->{int l=i.length()+2;return "#".repeat(l+2)+"\n#"+" ".repeat(l)+"#\n# "+i+" #\n#"+" ".repeat(l)+"#\n"+"#".repeat(l+2);}

Try it online!

Python 3, 68 bytes

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

Try it online!

Japt -h, 17 bytes

8Æ=z ®i" #"gXz4}R

Try it

Vyxal j, 29 bytes

L4+\#*:\#?L½›꘍m:„W2\#ð+Ḃ?$++Ṁ

Try it Online!

For some reason Vertical mirror and center doesn't work

05AB1E (legacy), 20 bytes

g4+'#ש,¹' .ø'#.ø,®,

Try it online!

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!

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.

J, 21 bytes

'#'g' '&g=.|.@|:@,^:4

Try it online!

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!

MAWP, 117 107 bytes

%|0_!!!3M[1A75W;]25W;%75W;1M[1A84W;]75W;25W;75W;84W;~[;]84W;75W;25W;%75W;1M[1A84W;]75W;25W;%3M[1A75W;]25W;.

-10 bytes from Dion.

Try it!

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 #

Perl 5 -n, 51 bytes

map{say"#$_#"}($_=" $_ ",y// /cr,y//#/cr)[2,1,0..2]

Try it online!

Haskell, 70 bytes

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.)


Haskell, 63 bytes

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

Try it online!

Python 3, 66 bytes

lambda x:("###### %s ######\n\n\n\n"%' ## '.join(f" {x} ")*5)[::5]

Try it online!

SmileBASIC, 73 bytes

LINPUT S$L=LEN(S$)+2O$="#"+" "*L+"#
T$="#"*(L+2)?T$?O$?"# ";S$;" #
?O$?T$

C (gcc) 165 bytes

f(*s){i,j;c='#';for(j=0;j<5;j++){if(j==0||j==4){for(i=0;i<strlen(s)+2;i++)printf("#");}else if(j==2) printf("#%s#",s);else printf("#%*c",(strlen(s)+1),c);puts("");

Ungolfed version

void  f(char *s)
{
    int i,j;
    char c='#';

    for(j=0;j<5;j++)
    { 
       if(j==0||j==4)
       { 
         for(i=0;i<strlen(s)+2;i++)
           printf("#");
       }
       else
        if(j==2)
         printf("#%s#",s);
      else
        printf("#%*c",(int)(strlen(s)+1),c);

   puts("");
}

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[0]} ":new string(" #"[i%2],a[0].Length+2));}}

Ungolfed:

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

PHP, 95 93 bytes

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

$l=strlen($s=" $argv[1] ");printf("#%'#{$l}s#
#%1\${$l}s#
#$s#
#%1\${$l}s#
#%1\$'#{$l}s#",'');

Not exactly pretty or anything, but it works brilliantly!


Thanks to @Titus for saving 2 bytes.

C#, 116 110 bytes

s=>{string r="\n".PadLeft(s.Length+5,'#'),p="#".PadRight(s.Length+3,' ')+"#\n";return r+p+"# "+s+" #\n"+p+r;};

Ungolfed:

s=>
{
    string r = "\n".PadLeft(s.Length + 5, '#'),         //the first line, made of '#'s
        p = "#".PadRight(s.Length + 3, ' ') + "#\n";    //the second line
    return r + p + "# " + s + " #\n" + p + r;           //output is simmetrical
};

Initial version:

s=>{int l=s.Length;string r=new string('#',l+4)+"\n",p="#"+new string(' ',l+2)+"#\n";return r+p+"# "+s+" #\n"+p+r;};

Full program with test cases:

using System;

namespace SurroundStringWithHashes
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<string,string>f= s=>{int l=s.Length;string r=new string('#',l+4)+"\n",p="#"+new string(' ',l+2)+"#\n";return r+p+"# "+s+" #\n"+p+r;};

            Console.WriteLine(f("Hello World"));
            Console.WriteLine(f("Programming Puzzles & Code Golf"));
        }
    }
}

Racket 172 bytes

(λ(s)(let((n(string-length s))(p #\space)(g(λ(l c)(make-string l c))))(display(string-append
(g(+ 4 n)#\#)"\n#"(g(+ 2 n)p)"#\n# "s" #\n#"(g(+ 2 n)p)"#\n"(g(+ 4 n)#\#)))))

Ungolfed:

(define (f s)
  (let ((n (string-length s))
        (p #\space)
        (g (λ (l c) (make-string l c))))
    (display (string-append (g (+ 4 n) #\#)
                            "\n#"
                            (g (+ 2 n) p)
                            "#\n# "
                            s
                            " #\n#"
                            (g (+ 2 n) p)
                            "#\n"
                            (g (+ 4 n) #\#)
                            ))))

Testing:

(f "This is a test" )

Output:

##################
#                #
# This is a test #
#                #
##################

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, 93 91 bytes

$b=str_pad("",$e=strlen($s=" $argv[1] "));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.

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///.

Ruby, 83 bytes

I guess it could be golfed further, but since there's no Ruby answer yet, here it is:

s=ARGV[0]
n=s.size
r="#"*(n+4)
t="\n#"+" "*(n+2)+"#\n"
puts r+t+"\n# "+s+" #\n"+t+r

Lua, 90 bytes

a=arg[1]h="#"s=" "t="\n"..h c=h:rep(#a+4)..t..s:rep(#a+2)..h..t..s print(c..a..c:reverse())

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! #
#                               #
#################################

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)
)   

><>, 106 104 Bytes

I get the feeling that ><> may not be the best language for this, but I've come too far to give up and not post this. The * at the end of line 4 is supposed to be a space. Don't you love how incredibly grotesque this code looks? Try it online.

<v?(0:i
v>~" ## "}}l:::
>"#"o1-:?!v02.>~a"#"oo
"-2ooa"#"~<.31v!?:-1o" 
7v?=3loroo"#"a<.4
.>";^"e3pa2p093

Here's a version without anything but direction changers to give an idea of how the pointer moves (note that I've left out the "teleport" statements, i.e. .).

Direction flow:

<v
v>
>         v   >
          <   v 
 v            <
 >           

Explanation

My visualization of the stack will be based off of the input input. ><> is a two dimensional language, so pay attention to where the pointer is moving between lines, as it executes code underneath it (in this code <>v^ are primarily used to change direction). I'll be starting my explanations from where the pointer starts. Note that there will be two lines repeated, as the pointer moves backwards after the fifth line.

What I always find cool about ><> is its ability to modify its own source code, and I make use of it in this program. Lines 3 and 4 are reused to print the last two lines through a modification of a character in each.

Line 1 : Input loop

<v?(0:i
<        change direction to left
   (0:i  checks if input is less than 0 (no input defaults to -1)
 v?      change direction to down if so

Stack: [-1,t,u,p,n,i]


Line 2: Generates third line of output

v>~" ## "}}l:::  
 >~" ## "}}      remove -1 (default input value) from stack and pads with # and spaces
           l:::  push 4 lengths of padded input

Stack: [9,9,9,9,#, ,t,u,p,n,i, ,#]


Line 3: Prints first line of output

>"#"o1-:?!v02.>~a"#"oo
>"#"o                   print "#"
     1-                 subtract 1 from length (it's at the top of the stack)
       :?!v             move down if top of stack is 0

Stack: [0,9,9,9,#, ,t,u,p,n,i, ,#]

Output:

#########

Line 4: Prints second line of output

"-2ooa"#"~<.31v!?:-1o"*
 -2ooa"#"~<              pops 0, prints newline, "#", then decrements length by 2
"                   o"*  prints space (* is supposed to be space char)
                  -1     decrements top of stack
           .31v!?:       changes direction to down if top of stack is 0, else jumps back to "

Stack: [0,9,9,#, ,t,u,p,n,i, ,#]

Output (* represents space):

#########
#*******

Line 5: Prints third line of output

7v?=3loroo"#"a<.4
        oo"#"a<    prints "#",newline
       r           reverses stack
7v?=3lo        .4  outputs until stack has 3 values, then changes direction to down

Stack: [9,9,0]

Output:

#########
#       #
# input #

Line 6: Sets itself up to print fourth and fifth lines of output

.>";^"e3pa2p093
 >";^"           push ";",then "^"
      e3p        place "^" as the fifteenth character on line 4
         a2p     place ";" as the eleventh character on line 3
            0    push a value (value doesn't matter -- it will be deleted)
.            93  jump to the tenth character on line 4

Stack: [0,9,9,0]


Line 4: Print fourth line of output

"-2ooa"#"~<.31^!?:-1o"*
   ooa"#"~<              delete 0 (unnecessary value pushed), then print newline,"#"
 -2                      subtract two from value on top of stack (length)
"          .31^!?:-1o"*  print space until top of stack is 0, then change direction to up

Stack: [0,9,0]

Output (* represents space):

#########
#       #
# input #
#*******

Line 3: Print last line of output

"#"o1-:?!;02.>~a"#"oo
             >~a"#"oo  pop top of stack, print "#", newline
"#"o1-:?!;02.          print "#" until top of stack is 0, then terminate

Stack: [0,0]

Output:

#########
#       #
# input #
#       #
#########

C++, 198 Bytes

#include <iostream>
#include <string>
int i;int main(){std::string t,n,o;std::getline(std::cin,o);t="\n#";o="# "+o+" #";for(;i<o.size();i++){n+="#";if(i>1)t+=" ";}t+="#\n";std::cout<<n+t+o+t+n;}

My first stab at codegolf, and while I learned C++ is probably not the best language for golfing, I felt I did decently(?) for my first try.

Ungolfed

#include <iostream>
#include <string>

int i;                              //globals default to a value of 0

int main()
{
    std::string t, n, o;
    std::getline(std::cin, o);

    t = "\n#";                      // t needs hashes at start and end, places hash at start here
    o = "# " + o + " #";            // put hash at each end of input

    for(; i < o.size(); i++) {
        n += "#";                   // fills n with hashes
        if(i > 1) {
            t += " ";               // fill t with spaces between hashes, has two fewer spaces than n has hashes
        }
    }
    t += "#\n";                     // puts final hash at end of t

    std::cout << n + t + o + t + n; // final output
}

n, o and t represent the fully hashed lines, the input (with hashes at each end) and the lines between the input and the hashed lines respectively.

PowerShell, 84 82 bytes

$l=$input.length+4;$p='#'*$l;$s=' '*$l;$p,$s,"  $input  ",$s,$p-replace'^ | $','#'

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.

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 lines are concatenated and printed.

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 #
#                #
##################

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.

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

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.

pb - 89 bytes

v[4]w[Y!-1]{b[35]^}w[B!0]{t[B]vvv>>b[T]^^^<}v>>>w[Y!4]{b[35]v}w[X!0]{b[35]^[Y]b[35]v[4]<}

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[4]           # 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[35]^         # 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
    b[35]v         # Draw "#", then go down
}

###########################
#                         #
# Loop to finish Y=0, Y=4 #
#                         #
###########################

w[X!0]{        # Until we've gone all the way left
    b[35]^[Y]      # Print "#" at Y=4, go to Y=0
    b[35]v[4]      # Print "#" at Y=0, go to Y=4
    <              # Move left, printing until output is complete
}

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],:

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[0].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[0].length))=>[z,...b,z].map(r=>c+r+c))('*',q(' ',[s])).join`\n`