O que está sendo cercado

18

Eu sempre quis cercar algum texto com #s, mas tenho dificuldade em descobrir o que cercava, então neste desafio você estará escrevendo um programa para fazer exatamente isso

Exemplos

As entradas / saídas são separadas por uma nova linha.

###
#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 são o que "envolve" um bloco de texto
  • # sempre estarão adjacentes um ao outro (incluindo na diagonal)
  • # sempre formará uma forma fechada
  • Haverá apenas uma #forma
  • No caso de uma forma côncava, os furos devem ser preenchidos com espaços.
  • O espaço em branco deve ser preservado na saída
Downgoat
fonte
no começo eu era como ... basta tirar os se #lá vai você ... e depois ficou difícil.
precisa saber é o seguinte
Estou tendo problemas para obter entrada em javascript e dividir por nova linha ... como preciso obter entrada? poderia ser formatado com um \napós cada linha de entrada e passado como um parâmetro de função para o meu programa ou o quê?
precisa saber é o seguinte
11
Qual é o conjunto de caracteres de entrada válidos?
precisa saber é o seguinte
Existe um erro na saída do exemplo MN ? Sua saída consiste apenas no texto cercado _M_\n___N(usando sublinhados em vez de espaços por causa de problemas de formatação), enquanto nos exemplos abc e Codego a saída também inclui um espaço em branco onde #s estavam na entrada. Se apenas o texto cercado por #s for impresso, a saída do exemplo abc deve ser _a_\n_b_c_(em vez de __a_\n_b_c) e a saída do exemplo Codego deve ser Co\nde\n_go(em vez de C___o\nd___e\n__go).
epidemian 14/04
ah ah epidemi, boa captura. Eu consertei o MNexemplo. como não de deve sido um espaço extra após M.
Downgoat

Respostas:

6

Perl, 144 138 132 129 128 127 126 124 bytes

Inclui +2 para -p0

O código assume que \0não é um caractere de entrada válido (pelo menos dentro do #).

Execute com a entrada em 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;#; 

O código funciona como está, mas substitua as versões literais \0e as \npela pontuação reivindicada. Observe que há um espaço no final da linha. O código faz um loop muitas vezes, portanto, talvez você precise esperar 30 segundos ou mais pela saída.

Explicação

Vou fazer um aterro com \0paradas #do lado de fora nas direções ortogonais. Depois disso, cortarei os #lados e substituirei tudo o que for deixado por espaços. Para evitar ter que lidar com todas as direções no aterro, girarei repetidamente a área de destino e apenas aterro da direita para a esquerda

/^#[^#\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)

Neste ponto, por exemplo

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

será substituído por:

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

Basicamente, todas as colunas e linhas que não estão diretamente próximas ao interior foram cortadas. Quaisquer caracteres externos restantes foram substituídos por \ 0. No topo e à direita, há uma camada extra de \ 0. Então, tudo o que resta é a limpeza:

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
Ton Hospel
fonte
Seus aterros sanitários funcionam nos cantos internos, se houver algum?
mbomb007
@ mbomb007: Sim, como a área é rotacionada repetidamente, ela pode seguir os corredores sinuosos. O loop parar muito cedo antes de reduzir paredes muito grossas é a única falha, tanto quanto eu sei
Ton Hospel
@ mbomb007: Aaaaand a falha de parede espessa é agora resolvido
Ton Hospel
Ao copiar e colar sua solução como está (não substituindo os caracteres de escape), a saída é apenas a entrada com todas as #opções removidas. verifique minha sessão bash: codepad.org/YbCzB4O4
ardnew
@ardnew: Opa, desculpe. A última atualização não reformulou a solução completa e eu deveria ter substituído o tempo por um até. Corrigido agora, por favor, tente novamente
Ton Hospel 15/16/16
4

Javascript, 48546444217396 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," ")}

Sim. Eu tentei. E, embora eu esteja com 485 bytes, estou ganhando porque ninguém mais teve vontade de responder a essa pergunta. Então, ah!
E também, estou ciente de que poderia jogar golfe, estou cansado no momento ... bem, agora estou com 396 anos. Graças a Conor pela maior parte do golfe ...: D

Bald Bantha
fonte
11
Declare as variáveis dentro do loops de fora comy=z=0
Bálint