Co jest otoczone

18

Zawsze chciałem otoczyć tekst #s, ale mam problem z ustaleniem, co otoczyłem, więc w tym wyzwaniu napiszesz program, który właśnie to robi

Przykłady

Wejścia / wyjścia są oddzielone znakiem nowej linii.

###
#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ą tym, co „otacza” blok tekstu
  • # zawsze będą przylegać do siebie (w tym po przekątnej)
  • # zawsze tworzy zamknięty kształt
  • Będzie tylko jeden #kształt
  • W przypadku wklęsłego kształtu otwory powinny być wypełnione spacjami.
  • W danych wyjściowych należy zachować białe znaki
Downgoat
źródło
na początku byłam jak ... po prostu wyjmij #s i proszę bardzo ... a potem stało się ciężko.
Bald Bantha,
Mam problem z uzyskaniem danych wejściowych w javascript i podziałem według nowego wiersza ... jak mam uzyskać dane wejściowe? czy można go sformatować \npo każdym wierszu danych wejściowych i przekazać jako parametr funkcji do mojego programu lub co?
Bald Bantha
1
Jaki jest zestaw prawidłowych znaków wejściowych?
Ton Hospel,
Czy wystąpił błąd na wyjściu z przykładu MN ? Jego wynik składa się tylko z tekstu otoczonego _M_\n___N(użycie podkreślników zamiast spacji ze względu na problemy z formatowaniem), podczas gdy w przykładach abc i Codego dane wyjściowe obejmują również spacje, gdzie #s były na wejściu. Jeśli ma być wydrukowany tylko tekst otoczony #s, to wynik z przykładu abc powinien być _a_\n_b_c_(zamiast __a_\n_b_c), a wynik z przykładu Codego powinien Co\nde\n_go(zamiast C___o\nd___e\n__go).
epidemia
@epidemian ah, nice catch. Naprawiłem MNprzykład. ponieważ po M. nie powinno być dodatkowej przestrzeni
Downgoat 14.04.16

Odpowiedzi:

6

Perl, 144 138 132 129 128 127 126 124 bajtów

Obejmuje +2 za -p0

Kod zakłada, że \0nie jest prawidłowym znakiem wejściowym (przynajmniej wewnątrz #).

Uruchom z wejściem na 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;#; 

Kod działa tak, jak jest, ale zastępuje \0i \nprzez ich dosłowne wersje dla żądanego wyniku. Zauważ, że na końcu linii jest spacja . Kod zapętla się zbyt wiele razy, więc może być konieczne poczekanie około 30 sekund na wyjście.

Wyjaśnienie

Zamierzam zrobić miejsce zalewowe z \0zatrzymaniem się #z zewnątrz w kierunkach ortogonalnych. Następnie odetnę #boki i zastąpię wszystko, co pozostało spacjami. Aby uniknąć konieczności obsługi wszystkich kierunków w zatopieniu, będę wielokrotnie obracać obszar docelowy i wypełniać tylko od prawej do lewej

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

W tym momencie np

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

zostanie zastąpiony przez:

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

Zasadniczo wycięto wszystkie kolumny i wiersze, które nie graniczą bezpośrednio z wnętrzem. Wszelkie pozostałe znaki zewnętrzne zostały zastąpione przez \ 0. U góry i po prawej stronie znajduje się dodatkowa warstwa \ 0. Pozostało więc tylko czyszczenie:

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
źródło
Czy twoje zalewy działają wokół wewnętrznych narożników, jeśli takie były?
mbomb007
@ mbomb007: Tak, ponieważ obszar jest wielokrotnie obracany, więc może podążać dowolnymi krętymi korytarzami. Pętla zatrzymująca się zbyt wcześnie przed zmniejszeniem bardzo grubych ścian jest jedyną wadą, o ile mi wiadomo
Ton Hospel,
@ mbomb007: Aaaa i gruba wada ściany jest już rozwiązana
Ton Hospel
kopiowanie i wklejanie twojego rozwiązania takim, jakim jest (nie zastępując znaków specjalnych), dane wyjściowe są jedynie danymi wejściowymi ze wszystkimi #odizolowanymi. proszę zweryfikuj moją sesję bash: codepad.org/YbCzB4O4
ardnew 15.04.16
@ardnew: Ups, przepraszam. Do ostatniej aktualizacji nie wkleiłem pełnego rozwiązania i powinienem był zamienić chwilę na till. Naprawiono teraz, spróbuj ponownie
Ton Hospel 15.04.16
4

JavaScript, 485 464 427 417 396 390 bajtów

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

Tak. Próbowałem. I chociaż mam 485 bajtów, wygrywam, ponieważ nikt inny nie miał ochoty odpowiadać na to pytanie. Hej!
A także jestem świadomy, że mogłem grać w golfa przy takich obciążeniach, jestem w tej chwili po prostu zmęczony ... no cóż, teraz mam 396 Dzięki Conorowi za większość golfa ...: D

Łysa Bantha
źródło
1
Zadeklaruj zmienne wewnątrz pętli for za pomocąy=z=0
Bálint