# What's being surrounded

I've always wanted to surround some text with #s, but I have trouble figuring out what I surrounded so in this challenge you'll be writing a program to do just that

## Examples

Input / Outputs are separated by a newline.

###
#a#
###

a

 #
#a#
#

a

  ###
# a #
# b c #
#######

a
b c

ABCDHIJ
E####GK
F# M #L
#   N#O
P####

M
N

###A###
#C#B#o#
#d###e#
# go#
###

C   o
d   e
go


## Spec

• #s are what "surround" a block of text
• # will always be adjacent to one another (including diagonally)
• # will always form a closed shape
• There will only be one # shape
• In the event of a concave shape, holes should be filled with spaces.
• Whitespace must be preserved in the output
• at first I was like.. just take out the #s and there you go... and then it got hard. – Bald Bantha Apr 10 '16 at 19:48
• I'm having trouble getting input in javascript and splitting by newline... how do I have to get input? could it be formatted with a \n after each line of input and passed as a function param to my program or what? – Bald Bantha Apr 10 '16 at 21:08
• Whats is the set of valid input characters ? – Ton Hospel Apr 12 '16 at 17:05
• Is there an error on the output of the MN example? Its output consists of only the text surrounded, _M_\n___N (using underscores instead of spaces because of formatting issues), while in the abc and Codego examples the output also includes whitespace where #s were in the input. If only the text surrounded by #s is to be printed, then the output of the abc example should be _a_\n_b_c_ (instead of __a_\n_b_c) and the output of the Codego example should be Co\nde\n_go (instead of C___o\nd___e\n__go). – epidemian Apr 14 '16 at 5:14
• @epidemian ah, nice catch. I've fixed the MN example. as there shouldn't of been an extra space after M. – Downgoat Apr 14 '16 at 5:39

# Perl, 144138132129128127126 124 bytes

Includes +2 for -p0

The code assumes \0 is not a valid input character (at least inside the #).

Run with the input on STDIN:

surround.pl < surround.txt


surround.pl:

#!/usr/bin/perl -p0
/^#[^#\0]/m&&s/^|[^#\n\0]\0/\0\0/mg,s%.%s/.(.*)/$+\0/g;/#/&&reverse"\n",/^./mg%seg until$?++<$$_++;y/\0/#/;s/^#*\n|#+|^#//mg;y;#;  The code works as is, but replace the \0 and \n by their literal versions for the claimed score. Notice there is a space at the end of the line. The code loops way too many times, so you may have to wait 30 seconds or so for output. ## Explanation I am going to do a floodfill with \0 stopped by # from the outside in the orthogonal directions. After that I will slice off the # sides and replace all that is left by spaces. To avoid having to handle all directions in the floodfill I will repeatedly rotate the target area and only floodfill from right to left /^#[^#\0]/m The rotation is written such that it slices off the first column. That is ok unless the first column contains a # that is followed by something that could be the inside. There is no newline inside the [] because short lines will get extended during the rotation and the character following the # will end up as a \0 and match in a later round &&s/^|[^#\n\0]\0/\0\0/mg In case the # could be an interior border I will add two columns of \0's in front. One will be a sacrifice for the rotation, the other column will end up at the end of the area after two rotations and function as seed for the floodfill. This regex also does one step of the floodfill from the back to the front. After a certain number of loops we are certain to get to a first column that must not be dropped so at some point the last column is guaranteed to consist of only \0. And we only need to fill backward since the rotations will make any direction backward at some point s%.% process column %seg I will replace each character (including \n) in the string by the next column in reversed order or an empty string if there are no more interesting columns. This is therefore a right rotation. There are less columns than characters so this loop is long enough s%.%s/.(.*)/+\0/g Remove the next (now first) character from each row (so remove the column). Because the original area is not necessarily a rectangle add a \0 at the end of the row so we won't run out out of columns (this would cause shorter rows to have no entry in the new rotated row) This will not do anything for empty lines so they DO get squeezed out. But that is not a problem since the problem statement says there will be only one # shape so any empty lines are can be safely dropped (this would not be so if there could be multiple # shapes because that could create a new surrounded area /#/ Check if any of the remaining columns still has a #. If not all remaining columns are on the outside and can be dropped &&reverse"\n",/^./mg Collect the column and add a \n to its reverse until?++<$$_++              Keep doing this until we get to a multiple of
65536 rotations when $? waraps back around to 0 (this is a multiple of 4 so the area is left unrotated) and an area we have seen before ($$_ >= 1) (so all slicing and flood filling is finished)$_ having been seen in a previous rotations is
not a problem (though rather tricky to prove)


At this point e.g.

AB##J
E####GK
F# M #L
#   N#O
P####


will have been replaced by:

0000000
0####00
0# M #0
#   N#0
0####00


Basically all columns and rows that are not directly bordering the inside have been sliced off. Any outside characters left has been replaced by \0. At the top and right there is an extra layer of \0. So all that is left is cleanup:

y/\0/#/                       Replace any outside that is left by #
s/^#*\n|#+\$|^#//mg            Removes the first two and last line (the only
lines that can consist of purely #)
Removes any trailing #
Removes the first column of #
y;#; \n;                      Replace any remaining # by space since they
are needed to fill the concave parts
The final \n; is not written since it is implicit
in the -p loop

• Do your floodfills work around interior corners, if there were any? – mbomb007 Apr 14 '16 at 21:24
• @mbomb007: Yes, since the area is repeatedly rotated, so it is able to follow any twisty corridors. The loop stopping too early before reducing very thick walls is the only flaw as far as I know – Ton Hospel Apr 15 '16 at 9:44
• @mbomb007: Aaaaand the thick wall flaw is now solved – Ton Hospel Apr 15 '16 at 14:03
• copy-pasting your solution as-is (not replacing the escaped chars), the output is merely the input with all # stripped. please verify my bash session: codepad.org/YbCzB4O4 – ardnew Apr 15 '16 at 16:38
• @ardnew: Oops, sorry. For the last update did not repaste the full solution, and I should have replaced the while by an until. Fixed now, Please try again – Ton Hospel Apr 15 '16 at 18:30

# Javascript, 485 464 427 417 396 390 bytes

s='indexOf';k='lastIndexOf';h="#";t=b=>b[0].map((x,i)=>b.map(x=>x[i]));i=>{m=i.split
;for(h of m){m[m[s](h)]=h.split;}for(y=0;y<m.length;y++){for(z=x=0;x<m[y].length;x++){if(m[y][x]==h)break;if(m[y][s](h)<x&&m[y][k](h)>x)z++;q=t(m);if(q[y][s]h)<x&&m[y][k](h)>x)z++;if(z>2)m[y][x]=h}}for(p of m){v=p.join.match(/\S/);e=v?p.join:'';m[m[s](p)]=e;}m=m.join
;return m.replace(#/g," ")}

Yes. I tried. And, although I am at 485 bytes, I am winning because no-one else felt like answering this question. So, hah!
And also, I am well aware that I could golf this loads, I just am tired at the moment... well now I'm at 396 Thanks to Conor for most of the golfing... :D

• Declare the variables inside the for loops outside with y=z=0 – Bálint Apr 28 '16 at 15:23