text:
Fixing a Froot Loop Necklace
Suppose you are stringing a strand of Froot Loops for a necklace, bracelet, shoelace, or whatever. There are 6 loop colors: red, orange, yellow, green, blue, and purple. You want your strand to start with red at the very left and cycle in rainbow order going right, ending with purple. That is, you want to make it so your strand could be represented by the string roygbp repeated some number of times (possibly 0).
The problem is, you've already strung your loops, and not in any particular order. Which loops should you eat and not eat so that you can maximize the number of correct rainbow cycles going from left to right, with the very first loop red and the very last loop purple?
Write a program or function that takes in an arbitrary string of the characters roygbp and prints or returns a string of the same length with e in the place of loops to eat and n in the place of loops to not eat.
For example, if your Froot Loop strand looked like

the input would be
gorboypbgbopyroybbbogppbporyoygbpr

and going from left to right we can find 3 complete roygbp rainbow sequences, but some of the loops need to be eaten away. Thus the output would be
eenenneennenennneeeeneennenennnnne

resulting in a perfect 3 cycle strand:

If there are no complete rainbow cycles in the input then the output would be all e's and the strand ends up loopless. e.g. the input proygb has output eeeeee. Conversely, proygbp has output ennnnnn.
You can assume all input strands have at least one loop.
The shortest code in bytes wins.

Do we have to find the best solution (that is, the one where we eat the least pieces)?

@Fatalize Yes. Note the part about maximizing the number of rainbow cycles. Else you could eat all of them.

You actually sorted and threaded those fruit loops to take the pictures, didn't you?

@MartinBüttner Of course

Does every rainbow cycle have to start at r or could oygbproygbpr also qualify?

@orlp It must start with r and end in p. See first paragraph and last example.

Yes, but if they're strung on a necklace or bracelet surely they can be rotated?

@PeterTaylor Yes. It could be reversed too. This just felt the easiest to explain and implement.

Can we assume input length smaller than some value?

@LuisMendo You can assume it won't be beyond standard integer size/computer memory limits.

Are fruit loops nice? They certainly look tasty

This would be much easier without the requirement that the output end with a complete cycle.

Fun Fact: All Froot Loops are the SAME FLAVOR! Now you can go on eating your delicious bowl of lies.

Doesn't a rainbow have 7 colors? ROY G. BIV. Red Orange Yellow Green Blue Indigo Violet.

@NateKerkhofs Take it up with Kellogg's.

@NateKerkhofs, no. The only reason that entered popular mythology is that Isaac Newton had some rather unusual beliefs, including some numerological ones.

Pyth, 31 bytes
:*lz\nhf!:jk.DzT"roygbp"kyUlz\e

Incredibly inefficient, explanation coming soon.
yUlz generates all possible subsets of all possible indices of z (the input) in order. E.g. if the input is abc:
[[], [0], [1], [2], [0, 1], [0, 2], [1, 2], [0, 1, 2]]

Then hf! finds the first T in the above list such that :jk.DzT"roygbp"k is false. .D takes a string and list of indices, and deletes the elements at those indices. So .D"abcd",1 3 is "ac". Since .D returns a list (which should not be the case, will fix in future versions of Pyth), I use jk (k is "") to join it together back into a string. The :_"roygbp"k part replaces every instance of a cycle with the empty string.
Since the empty string is false, the above paragraphs explain how I find the smallest set of indices needed to eat to get a string  consisting only of cycles.
:*lz\n_\e then turns that list of indices into an nnnneeennene string.

Hexagony, 920 722 271 bytes
Six different types of fruit loops, you say? That is what Hexagony was made for.
){r''o{{y\p''b{{g''<.{</"&~"&~"&<_.>/{.\.....~..&.>}<.._...=.>\<=..}.|>'%<}|\.._\..>....\.}.><.|\{{*<.>,<.>/.\}/.>...\'/../==.|....|./".<_>){{<\....._>\'=.|.....>{>)<._\....<..\..=.._/}\~><.|.....>e''\.<.}\{{\|./<../e;*\.@=_.~><.>{}<><;.(~.__..>\._..>'"n{{<>{<...="<.>../

Okay, it wasn't. Oh god, what did I do to myself...
This code is now a hexagon of side length 10 (it started out at 19). It could probably be golfed some more, maybe even to size 9, but I think my job is done here... For reference, there are 175 actual commands in the source, many of which are potentially unnecessary mirrors (or were added to cancel out a command from a crossing path).
Despite the apparent linearity, the code is actually two-dimensional: Hexagony will rearrange it into a regular hexagon (which is also valid code, but all whitespace is optional in Hexagony). Here is the unfolded code in all its... well I don't want to say "beauty":
          ) { r ' ' o { { y \
         p ' ' b { { g ' ' < .
        { < / " & ~ " & ~ " & <
       _ . > / { . \ . . . . . ~
      . . & . > } < . . _ . . . =
     . > \ < = . . } . | > ' % < }
    | \ . . _ \ . . > . . . . \ . }
   . > < . | \ { { * < . > , < . > /
  . \ } / . > . . . \ ' / . . / = = .
 | . . . . | . / " . < _ > ) { { < \ .
  . . . . _ > \ ' = . | . . . . . > {
   > ) < . _ \ . . . . < . . \ . . =
    . . _ / } \ ~ > < . | . . . . .
     > e ' ' \ . < . } \ { { \ | .
      / < . . / e ; * \ . @ = _ .
       ~ > < . > { } < > < ; . (
        ~ . _ _ . . > \ . _ . .
         > ' " n { { < > { < .
          . . = " < . > . . /

Explanation
I won't even try and begin explaining all the convoluted execution paths in this golfed version, but the algorithm and overall control flow are identical to this ungolfed version which might be easier to study for the really curious after I've explained the algorithm:
                 ) { r ' ' o { { \ / ' ' p { . . .
                . . . . . . . . y . b . . . . . . .
               . . . . . . . . ' . . { . . . . . . .
              . . . . . . . . \ ' g { / . . . . . . .
             . . . . . . . . . . . . . . . . . . . . .
            . . . . . . . . . . . . . . . . . . . . . .
           . . . . . . . . > . . . . < . . . . . . . . .
          . . . . . . . . . . . . . . > . . ) < . . . . .
         . . . . . . . . . . / = { { < . . . . ( . . . . .
        . . . . . . . . . . . ; . . . > . . . . . . . . . <
       . . . . . . . . . . . . > < . / e ; * \ . . . . . . .
      . . . . . . . . . . . . @ . } . > { } < . . | . . . . .
     . . . . . / } \ . . . . . . . > < . . . > { < . . . . . .
    . . . . . . > < . . . . . . . . . . . . . . . | . . . . . .
   . . . . . . . . _ . . > . . \ \ " ' / . . . . . . . . . . . .
  . . . . . . \ { { \ . . . > < . . > . . . . \ . . . . . . . . .
 . < . . . . . . . * . . . { . > { } n = { { < . . . / { . \ . . |
  . > { { ) < . . ' . . . { . \ ' < . . . . . _ . . . > } < . . .
   | . . . . > , < . . . e . . . . . . . . . . . . . = . . } . .
    . . . . . . . > ' % < . . . . . . . . . . . . . & . . . | .
     . . . . _ . . } . . > } } = ~ & " ~ & " ~ & " < . . . . .
      . . . \ . . < . . . . . . . . . . . . . . . . } . . . .
       . \ . . . . . . . . . . . . . . . . . . . . . . . < .
        . . . . | . . . . . . . . . . . . . . . . . . = . .
         . . . . . . \ . . . . . . . . . . . . . . . . / .
          . . . . . . > . . . . . . . . . . . . . . . . <
           . . . . . . . . . . . . . . . . . . . . . . .
            _ . . . . . . . . . . . . . . . . . . . . .
             . . . . . . . . . . . . . . . . . . . . .
              . . . . . . . . . . . . . . . . . . . .
               . . . . . . . . . . . . . . . . . . .
                . . . . . . . . . . . . . . . . . .
                 . . . . . . . . . . . . . . . . .

Honestly, in the first paragraph I was only half joking. The fact that we're dealing with a cycle of six elements was actually a great help. The memory model of Hexagony is an infinite hexagonal grid where each edge of the grid contains a signed arbitrary-precision integer, initialised to zero.
Here is a diagram of the layout of the memory I've used in this program:

The long straight bit on the left is used as a 0-terminated string a of arbitrary size which is associated with the letter r. The dashed lines on the other letters represent the same kind of structure, each one rotated by 60 degrees. Initially, the memory pointer points at the edge labelled 1, facing north.
The first, linear bit of the code sets the inner "star" of edges to the letters roygbp as well as setting the initial edge to 1, such that we know where the cycle ends/begins (between p and r):
){r''o{{y''g{{b''p{

After this, we're back on the edge labelled 1.
Now the general idea of the algorithm is this:

For each letter in the cycle, keep reading letters from STDIN and, if they are different from the current letter, append them to the string associated with that letter.
When we read the letter we're currently looking for, we store an e in the edge labelled ?, because as long as the cycle is not complete, we have to assume that we'll have to eat this character as well. Afterwards, we'll move around the ring to the next character in the cycle.
There are two ways this process can be interrupted:

Either we've completed cycle. In this case, we make another quick round through the cycle, replacing all those es in the ? edges with ns, because now we want that cycle to remain on the necklace. Then we move on to printing code.
Or we hit EOF (which we recognise as a negative character code). In this case, we write a negative value into the ? edge of the current character (so that we can easily distinguish it from both e and n). Then we search for the 1 edge (to skip the remainder of a potentially incomplete cycle) before moving to printing code as well.

The printing code goes through the cycle again: for each character in the cycle it clears the stored string while printing an e for each character. Then it moves to the ? edge associated with the character. If it's negative, we simply terminate the program. If it's positive, we simply print it and move on to the next character. Once we complete the cycle we go back to step 2.

Another thing that might be interesting is how I've implemented the arbitrary-size strings (because it's the first time I've used unbounded memory in Hexagony).
Imagine we're at some point where we're still reading characters for r (so we can use the diagram as is) and a[0] and a1 have already been filled with characters (everything north-west of them is still zero). E.g. maybe we've just read the first two characters og of the input into those edges and are now reading a y.
The new character is read into the in edge. We use the ? edge to check whether this character is equal to r. (There's a nifty trick here: Hexagony can only distinguish between positive and non-positive easily, so checking for equality via subtraction is annoying and requires at least two branches. But all the letters are less than a factor of 2 from each other, so we can compare the values by taking the modulo, which will only give zero if they are equal.)
Because y is different from r, we move the (unlabelled) edge left of in and copy the y there. We now move further around the hexagon, copying the character one edge further each time, until we have the y on the edge opposite of in. But now there is already a character in a[0] which we don't want to overwrite. Instead, we "drag" the y around the next hexagon and check a1. But there's a character there as well, so we go another hexagon further out. Now a[2] is still zero, so we copy the y into it. The memory pointer now moves back along the string towards the inner ring. We know when we've reached the beginning of the string, because the (unlabelled) edges between the a[i] are all zero whereas ? is positive.
This will probably be a useful technique for writing non-trivial code in Hexagony in general.

...wow. Just wow.

It may not win the golf challenge, but... man, that's a neat solution...

Since groups of dots in a row seem to occur often in the source, maybe you could add a feature to the language for run-length encoding of dots or something to cut down on code length.

@mbomb007 Golfing really isn't that much of a priority in Hexagony. ;) Besides, I don't have any characters left to distinguish run-length encoding from actual code... (And I think really well golfed code wouldn't even have these runs of no-ops.)

Hexagony, 169 bytes
I was inspired by Martin Büttner’s answer (it’s his esolang, too) and decided I can do it in size 8. (I’m convinced it’s possible in size 7, too, but it’s very difficult. I’ve already spent four days non-stop on this.)
r'.'o\|{##|_#{#>\_{b{"]_\..<>"<>\/><#y/''"_<.}]''/'\>)}}.\}}'{<"\\#_#/<|##|#@#"p><n'>"{,<##g#_/#'.\<\##'#{(.<#e;#"\##%\\(};/*#>.)\>##_/"{__\}#>}=\#>=<|>##)|###_'#\"{__\\

Laid out hexagonally:
       r ' . ' o \ | {
      # # | _ # { # > \
     _ { b { " ] _ \ . .
    < > " < > \ / > < # y
   / ' ' " _ < . } ] ' ' /
  ' \ > ) } } . \ } } ' { <
 " \ \ # _ # / < | # # | # @
# " p > < n ' > " { , < # # g
 # _ / # ' . \ < \ # # ' # {
  ( . < # e ; # " \ # # % \
   \ ( } ; / * # > . ) \ >
    # # _ / " { _ _ \ } #
     > } = \ # > = < | >
      # # ) | # # # _ '
       # \ " { _ _ \ \

The program does not actually use the # instruction, so I’ve used that character to show which cells are actually unused. Furthermore, every no-op cell that is traversed in only one direction is a mirror (e.g. _ if traversed horizontally), so you know all the . characters are traversed in more than one direction.
Explanation
At the start, we execute the sequence of instructions r''o{{y''g{{b''p"")". These are strewn a bit haphazardly across the code because I squeezed them in after I wrote everything else. I use ] to switch to the next instruction pointer a few times; this way I can essentially teleport to another corner of the hexagon. The entire rest of the program is executed by instruction pointer #3.
The memory now looks as follows, with the important edges labeled with names I will use in this explanation:

The labeled edges mean the following:

in: We use this edge to store a character we read from STDIN.
%: We use this edge to perform a modulo operation on the character read from STDIN (in) and the current “valid” character (r, o, etc.), which will be 0 if they are equal. I stole this trick from Martin Büttner’s answer, but the rest of the program is different.
#: For as long as we read “invalid” characters (i.e. colors we need to eat), we increment this edge. Thus, this edge remembers how many es we need to output later.
r?: Always 0 except where the r (red) part is. This tells us when we’ve completed a cycle.

The program proceeds thusly:

Keep reading characters. If it’s not the character we’re currently looking for, increment #. Otherwise move to the next segment of the memory in clockwise order.
When moving to the next segment, if r? is positive, we’ve made a whole revolution. Make a complete round and output # es and 1 n per segment. This sets each # back to 0. (The e is placed on an unlabeled edge, but for the n we misappropriate the # edge, which we set to 0 using a * (multiplication) afterwards, which works because we know that all the % edges are zero at this time.)
When reading a character, if it is not positive (i.e., EOF), go backwards through the circle and output #+1 es until you get back to where r? is positive, then exit.

After a complete run, the memory looks approximately as follows at the end. You will notice the edges containing 101 (the ASCII code of e); one of the in edges is -1 (EOF); all the # edges are at 0; and the memory pointer ends at the positive r? edge.

Retina, 148 85 79 bytes
$
#roygbp
.(?<=(?=((?=.*#(\2?(.))).*?\3(?<=^\5())?)+.*\3$)(.*))\4
n
#.*

[^n]
e

You can run this from a single source file with the -s interpreter flag.
Explanation
Let's get the simple stuff out of the way first:
$
#roygbp

Appends #roygbp to the end of the string, which we'll use to compute the cycle of letters dynamically.
The next (long) step figures out which loops to keep and replaces them with n. We'll look into how this works in a bit.
#.*
<empty>

This gets rid of our lookup helper at the end of the string.
[^n]
e

This replaces all characters that weren't replaced in the second step with e, completing the transformation.
Now let's go back to the second step.
The basic structure uses a trick, which I discovered a few months ago to replace selected characters in a global match:
.(?<=(?=...(?<=^\k<prefix>(?<flag>))?...)^(?<prefix>.*))\k<flag>

where ... corresponds to an arbitrarily complex pattern. This matches the character to be replaced with . and then starts a lookbehind (which you should read from right to left). The lookbehind captures everything up to the matched character into a group prefix. Then it switches to a lookahead, which now starts from the beginning of the string and can contain a complex pattern. After the character which we want to replace in that pattern, we put an optional lookbehind, which checks if the prefix group matches here. If it does, it captures an empty string into the flag group. If it doesn't, because it's optional, it doesn't affect the state of the regex engine at all and is ignored. Finally, once the lookahead is matched successfully, only the \k<flag> at the end is left which only matches if the flag was set at some point during the computation.
Now let's ungolf the long regex a bit by using named groups and freespacing mode:
.
(?<=
  (?=
    (?:
      (?=
        .*#
        (?<cycle>
          \k<cycle>?
          (?<char>)
        )
      )
      .*?
      \k<char>
      (?<=^\k<prefix>(?<flag>))?
    )+
    .*
    \k<char>$
  )
  (?<prefix>.*)
)
\k<flag>

I hope you recognise the general outline from above, so we only need to look at what I filled in for ....
We want to capture the next character in the cycle into the group char. We do this by also remembering the string from # to the current character in cycle. To get the next character, we use a lookahead to search for the #. Now we try to match cycle and then match the next character in char. This will usually be possible, unless char is the last character p. In this case, \k<cycle> will match the entire remainder of the string and there won't be a character left to capture into char. So the engine backtracks, omits the backreference to cycle and just matches the first character r instead.
Now we've got the next character in the cycle in char, we search for next possible occurrence of that character with .*?\k<char>. These are the characters we want to replace, so we put the prefix check after it. These steps (find the next char in the cycle, search for the next occurrence of it, set flag if appropriate) are now simply repeated with a +.
That's actually all there is to finding the cyclic subsequence, but we also need to make sure that we end on a p. This is fairly easy: just check that the value currently stored in char matches the p at the end of the string with .*\k<char>$. This also ensures that our lookup string isn't used to finish an incomplete cycle, because we need the trailing p for this check.

Python 2, 133 130 126 121 bytes
r=n=''
for c in input():r+='en'[c=='roygbp'[r.count('n')%6]]
for c in r:n+=['e',c][n.count('n')<r.count('n')/6*6]
print n

The first loop gets cycles, and the second removes an incomplete cycle
Saved 3 bytes thanks to J F and 5 from DLosc

Couldn’t you combine the initialization of r and n like this: r=n=''?

Assigning R=r.count doesn't work as strings are immutable so R is ''.count even when r is changed.

Perl 5, 76 65 bytes
A pinch of pure undiluted regular expressions.
First finds what shouldn't be eaten. What remains is eatable.
s/r(.*?)o(.*?)y(.*?)g(.*?)b(.*?)p/n$1n$2n$3n$4n$5n/g;s/[^n\s]/e/g

Test
$ perl -p fruitloops.pl <<<gorboypbgbopyroybbbogppbporyoygbpr
eenenneennenennneeeeneennenennnnne

I like this approach. Instead of [^o]* etc., can you use .*? (non-greedy quantifier)?

Great tip, thanks!  I wasn't aware that the non-greedy qualifier would come in handy.

If you want to avoid replacing trailing spaces, you can use\s instead of \n in the negative character class of the first version.

Same approach in Retina: r(.*?)o(.*?)y(.*?)g(.*?)b(.*?)p n$1n$2n$3n$4n$5n [^n\s] e (4 files, 57 bytes).

Oh right. \s includes also the linefeeds. Good catch. And good to hear that Retina can at least beat Perl at it's own game.

Lua, 101 bytes
s=arg[1]:gsub("r(.-)o(.-)y(.-)g(.-)b(.-)p.-","*%1*%2*%3*%4*%5*"):gsub("%w","e"):gsub("*","n")print(s)

Uses Lua patterns creatively; I think it's an interesting approach.
It replaces all non-eaten characters with "*"s, replaces all alphanumeric characters with "e"s, then replaces all "*"s with "n"s.

Javascript (ES6), 118
a=>eval("b=[...a],d=0,e=b.map(f=>f=='roygbp'[d%6]?'n'[++d&0]:'e');for(i=e.length-1;i&&b[i]!='p';e[i--]='e');e.join``")

Fiddle tested in Firefox. I hear Chrome supports arrow functions now but I haven't tested this in Chrome yet.
Ungolfed:
input=>eval("
    array = [...input],
    rainbow_index = 0,
    mapped = array.map( item=>
        item == 'roygbp'[rainbow_index%6] ? 'n'[++rainbow_index&0] : 'e'
        // when we encounter an item of the rainbow, do not eat and start using
        // the next rainbow item, otherwise eat
    );
    // go through backwards and eat until we find a 'p' indicating the last
    // complete loop
    for(i = mapped.length - 1; i && array[i]!='p'; mapped[i--] = 'e');

    mapped.join``
")

Chrome does support arrow functions but apparently not the ... notation yet.

gawk, 96
{for(;c=substr("roygbp",++i,1);r=r"\\"i"n")p=p"([^"c"]*)"c;$0=gensub(p,r,"g");gsub(/[^n]/,"e")}1

Constructs the search pattern "([^r]*)r([^o]*)o([^y]*)y([^g]*)g([^b]*)b([^p]*)p" and the replacement "\\1n\\2n\\3n\\4n\\5n\\6n". After that replacement it declares everything food ("e"), that's not part of a complete rainbow.
This combination automatically ensures, that no rainbows will be harmed during this operation, and no severed rainbows show up at the end.

Pyth, 42 bytes
Jf-Z=+Zq@zT@"roygbp"ZUzs.e@"en"}k<J*6/lJ6z

Try it online: Demonstration

CJam, 41 bytes
2r:R,m*{R.*s__,6/"roygbp"*=\,~*}$0="en"f=

Brute-force approach that tries all eat/not-eat variations and selects the one that results in the longest, valid necklace.
Try it online in the CJam interpreter.

CJam, 50 bytes
l{"roygbp"T=={'nT):T;}{'e}?}%W%_'ne=6%{_'n#'et}*W%

Try it online
This is a little longer than some of the other submissions, but it is very efficient with linear complexity. It scans through the input string, and matches characters one by one.
The core part of the algorithm is actually fairly compact. About half of the code is for removing the incomplete cycle at the end.

Javascript (ES6), 85 82 bytes
The "necklace must end in a purple" rule was originally a great hurdle, increasing my score from 66 to 125, but I found a shorter way over it (thankfully!).
s=>(i=j=0,s.replace(/./g,x=>s.lastIndexOf`p`>=j++&x=='roygbp'[i%6]?(i++,'n'):'e'))

Explanation:
This code loops through each character in the input and replaces each with r or e with this logic:

If the character's position is <= the last position of p, AND the character is the next one in the rainbow, keep it (replace it with n).
Otherwise, eat it (replace it with e).

Ungolfed:
function a(s) {
  var i=0, j=0, r='';
  t = t.replace(/./g, function (x) {
    if (s.lastIndexOf('p') >= j++ && x == 'roygbp'.charAt(i)) {
      i++;
      i %= 6;
      return 'n';
    } else {
      return 'e';
    }
  });
  return r;
}

Suggestions welcome!

C90, 142-146 bytes (down to 119, depending)
Operates in linear time to efficiently eat those fruit loops that can't be part of a pretty rainbow.  Then, a postprocess kills any partial loop at the end.
Here are four versions:

Version 1 (146 bytes), call with [name] [string]:main(int a,char**b){char*v=b[1],*s="roygbp",i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';while(k-->0)v[--i]='e';puts(v);}
Version 2 (142 bytes), call with [name] [string] [rainbow order]:main(int a,char**b){char*v=b[1],*s=b[2],i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';while(k-->0)v[--i]='e';puts(v);}
This allows you to define your own rainbow ordering with any colors you want so long as they aren't n or e.  This actually makes the code shorter!
Version 3 (123 bytes), call like version 1:main(int a,char**b){char*v=b[1],*s="roygbp",i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';puts(v);}
This one gives you as much of your rainbow as possible!  The incomplete trailing rainbows show promise!  We shouldn't eat them!
Version 4 (119 bytes), call like version 2:main(int a,char**b){char*v=b[1],*s=b[2],i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';puts(v);}
Same as version 3, but MOAR RAINBOW TYPES!

Minor limitation: machine must have signed chars (the general case), and string must be fairly short.  Outputs a trailing \n for clarity.
Version 1 is the only one that clearly passes the requirements, although version 2 is arguable.  Versions 3 and 4 are less-correct (but still fun) interpretation of the question.

Pyth, 38 bytes
I know this is significantly longer than orlp's answer, but this one runs in linear time :o)
u+G?qH@"roygbp"/G\n\n\e+_>_zJx_z\p*Jdk

Try it out here.
In brief, this program replaces all characters after the final 'p' with spaces, then iterates over each character in the resulting string. If the character is the next in the 'roygbp' sequence, print 'n', otherwise print 'e'.
                                          Implicit: z=input(), d=' ', k=''
                            Jx_z\p        Find number of chars after last p, store in J
                        _>_zJ             Take all but J chars of the input
                       +          *Jd     Append J spaces
u                                    k    Reduce on the above, starting with ''
               /G\n                       Count 'n' in output so far
      @"roygbp"                           Take relevant char from sequence string (modulus indexing)
   ?qH                                    Does the current char equal the above?
 +G                \n\e                   Select 'n' or 'e' as appropriate and append

I've struggled to find a shorter way to process the input string. _>_zJ in particular feels awkward, but <Jz doesn't give the required string when J == 0, i.e. when the input ends with a 'p'.

Haskell, 138 bytes
g does it.
f(c:r)(h:t)|c==h='n':(f(r++[c])t)|0<1='e':(f(c:r)t)
f _""=""
z 'n' 'n'='n'
z a b='e'
r=reverse
g s=zipWith z(f"roygbp"s)(r$f"pbgyor"(r s))

I think you can save some bytes by defining f and z as infix: 'n'%'n'='n' etc. Also, some parentheses in the definition of g can be removed with $.

Python 2, 254 bytes
Loops!
i=raw_input();r='roygbp';l='r';d=''
for n in i:
 if n==l:d+='n';l=r[(r.index(l)+1)%6]
 else:d+='e'
d=list(d)[::-1];p=(r.index(l)+1)%6;
for s in range(len(d)):
 if d[s]=='n'and p-1:d[s]='e';p-=1
if d.count('n')<6:print'e'*len(d)
else:print''.join(d[::-1])

Excuse the pun. :P


text:
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.

@MartinBüttner Not exactly the same, different input format, this requires spacing all around the phrase. Also not language-restricted.

@orlp Well this task is a subset of this challenge.

Not so different: http://codegolf.stackexchange.com/questions/57442/show-tree-rings-age/57470#57470

The input string won't contain linebreaks, right?

@edc65 I disagree, this challenge is hugely different

@BetaDecay not a duplicate, just similar

@edc65 Meh, debatable :)

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.

What about strings like s̄trin̂gs with 8 code points but only 6 columns, or strings like  ｗｉｄｅ with 8 columns but only 4 code points? What about tabs?

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!

I love the explanation :-D

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.

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
}

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

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.

Why using ; instead of new lines btw? Both should be one byte, right?

@JeromeJ I know it doesn't make a difference, but it looks shorter if you put it on one line ;)

72 bytes

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

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

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

@rayryeng It made me sad that nobody was submitting in Perl.

To be honest I was surprised.  This certainly seems like a problem suited for it :).

@rayryeng Fixed in the next release. :)

You already had my vote :D BTW, I hope this isn't shameless, but your book is awesome.  I use it for reference, but I still can't use it (and Perl) as eloquently as I'd like.

@rayryeng The Deparse trick is useful for figuring out precedence and implicits.

You can save some bytes by replacing length with y///c, swapping " " for $", and using multiple statements instead of all those parens: s/.*/$x="#"x(4+($z=y!!!c));$y="#".$"x(2+$z)."#\n";"$x\n$y# $& #\n$y$x"/e, which comes to 74 bytes (72 + 2 for -lp). (It's no longer necessary in this version, but in general you can use .$/. instead of ."\n". to save 2 bytes.)

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.

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[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!')

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`

Doesn't run for me (Canary).

@minxomat what is Canary?

It works in Chrome 45.0.2454.85 m, Windows 7

Canary is always the latest Chrome build. Doesn't work in my Chrome Stable either. Edit: Works in FireFox though.

(Is it legal to assign to the global z as a side-effect?)

@Neil yes. The goal is shortest code, not best practices

Gosh, something crazy happened.. This (cutting edge ;p) code worked in that peasant like browser called IE :p

@RandomUser wow! IE what? on my MSIE (11.0.9600.18015 auto update on) it does not work at all

Well, It's technically Microsoft Edge, but it's based heavily on IE 11..

@RandomUser Well, it's technically another JS engine, or else this script would work on IE11 as well. A good news anyway

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.

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.

You can save two bytes by using $argv instead of $_GET and -r.

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

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

Here's a golfed version to update if you're still active. I might edit yours since mine is just a direct golfing of your code down to 61 chars.
Update:
s=$*[0]
puts r=?#*n=s.size+4,t=?#+' '*(n-2)+?#,"# #{s} #",t,r
Yours:
s=ARGV[0]
n=s.size
r="#"*(n+4)
t="\n#"+" "*(n+2)+"#\n"
puts r+t+"\n# "+s+" #\n"+t+r

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.

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!

This is impressive, it's the kinda thing even i didnt expect from MAWP... Well done!

It seems that i have outgolfed you by quite a bit... :D

It seems that your submission with newlines being 25W instead of 25W3M is a byte shorter than mine! https://8dion8.github.io/MAWP/?code=%25%7C0_!!!3M%5B1A75W%3B%5D25W%3B%2575W%3B1M%5B1A84W%3B%5D75W%3B25W%3B75W%3B84W%3B~%5B%3B%5D84W%3B75W%3B25W%3B%2575W%3B1M%5B1A84W%3B%5D75W%3B25W%3B%253M%5B1A75W%3B%5D25W%3B.&input=Hello%20World

What luck! Changed it.

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!

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

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

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

05AB1E (legacy), 20 bytes
g4+'#×©,¹' .ø'#.ø,®,

Try it online!

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.

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

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.

@Razetime welp... i knew something was wrong with it. facepalm

@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?

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.

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

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!

You should use a pattern guard rather than a lambda for your binding.

Also >>=id is usually shorter than concat.

Good ideas! Also combined two of the string literals.

I spent a little longer with this and came up with a 57 byte variation that abuses do notation to get a slight advantage.

Perl 5 -n, 51 bytes
map{say"#$_#"}($_=" $_ ",y// /cr,y//#/cr)[2,1,0..2]

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.

101 bytes...

Vyxal j, 29 bytes
L4+\#*:\#?L½›꘍m:„W2\#ð+Ḃ?$++Ṁ

Try it Online!
For some reason Vertical mirror and center doesn't work

APL (Dyalog Unicode), 19 bytes
(⍉⍪⍪⊣)/'##  ',⊂∘⍉∘⍪

Try it online!

Stax, 14 bytes
≡┼ö▓ú¡êqct╜R"Γ

Run and debug it

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

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

Attempt This Online!

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

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

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"));
        }
    }
}

Use var instead of string.

Won't help in this case, since I have 2 strings and each var keyword allows only one declaration.

Oops, didn't see the second one :D

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

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("");
}

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

Try it online!

I would recommend splitting this into two separate answers, as the languages are very different. Also, non-competitive answers are no longer a thing, so don't worry about the new features

Thanks for the advice. Didn't know that non-competitive wasn't a thing anymore, just saw that one of the other answers mentioned it. I'll move the Haskell one to a different answer.

Here is a version that takes input and prints. It costs 4 bytes. print(("###### %s ######\n\n\n\n"%' ## '.join(f" {input()} ")*5)[::5])

Regenerate, 38 bytes
(\#{#~1+4})(\n# {#~1+2}#\n)# $~1 #$2$1

Takes the string as a command-line argument. Try it here!
Explanation
Spaces are replaced by underscores so they're easier to see.
(         )                             Group 1: top row
 \#                                      A literal hash character
   {     }                               repeated
    #~1                                  len(input)
       +4                                + 4 times
           (              )             Group 2: second row (plus newlines)
            \n#                          Newline followed by hash
               _{     }                  followed by space repeated
                 #~1+2                   len(input) + 2 times
                       #\n               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

Japt -h, 17 bytes
8Æ=z ®i" #"gXz4}R

Try it

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

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!

Can omit the space after return

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.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes