Apa yang dikepung

18

Saya selalu ingin mengelilingi beberapa teks dengan #s, tetapi saya mengalami kesulitan mencari tahu apa yang saya dikelilingi sehingga dalam tantangan ini Anda akan menulis sebuah program untuk melakukan hal itu

Contohnya

Input / Output dipisahkan oleh baris baru.

###
#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 adalah apa yang "mengelilingi" blok teks
  • # akan selalu berdekatan satu sama lain (termasuk secara diagonal)
  • # akan selalu membentuk bentuk tertutup
  • Hanya akan ada satu #bentuk
  • Dalam hal bentuk cekung, lubang harus diisi dengan ruang.
  • Spasi harus disimpan dalam output
Downgoat
sumber
pada awalnya saya seperti .. hanya mengambil #dan di sana Anda pergi ... dan kemudian menjadi sulit.
Bald Bantha
Saya mengalami kesulitan mendapatkan input dalam javascript dan dipisah dengan baris baru ... bagaimana saya harus mendapatkan input? Bisakah itu diformat dengan \nsetelah setiap baris input dan dilewatkan sebagai parameter fungsi untuk program saya atau apa?
Bald Bantha
1
Apa set karakter input yang valid?
Ton Hospel
Apakah ada kesalahan pada output dari contoh MN ? Keluarannya hanya terdiri dari teks yang dikelilingi, _M_\n___N(menggunakan garis bawah alih-alih spasi karena masalah pemformatan), sedangkan dalam contoh abc dan Codego output juga termasuk spasi putih di mana #s berada di input. Jika hanya teks yang dikelilingi oleh #s yang akan dicetak, maka output dari contoh abc harus _a_\n_b_c_(bukan __a_\n_b_c) dan output dari contoh Codego harus Co\nde\n_go(bukan C___o\nd___e\n__go).
epidemi
@epidemian ah, tangkapan yang bagus. Saya sudah memperbaiki MNcontohnya. karena seharusnya tidak ada ruang ekstra setelah M.
Downgoat

Jawaban:

6

Perl, 144 138 132 129 128 127 126 124 byte

Termasuk +2 untuk -p0

Kode menganggap \0bukan karakter input yang valid (setidaknya di dalam #).

Jalankan dengan input pada 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;#; 

Kode berfungsi sebagaimana adanya, tetapi ganti \0dan \ndengan versi literalnya untuk skor yang diklaim. Perhatikan ada spasi di ujung garis. Kode loop terlalu sering, jadi Anda mungkin harus menunggu sekitar 30 detik untuk output.

Penjelasan

Saya akan melakukan penimbunan dengan \0mampir #dari luar ke arah orthogonal. Setelah itu saya akan mengiris #sisi dan mengganti semua yang tersisa oleh spasi. Untuk menghindari harus menangani semua arah di TPA saya akan berulang kali memutar area target dan hanya mengisi TPA dari kanan ke kiri

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

Pada titik ini mis

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

akan diganti oleh:

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

Pada dasarnya semua kolom dan baris yang tidak berbatasan langsung dengan bagian dalam telah dipotong. Setiap karakter luar yang tersisa telah diganti oleh \ 0. Di bagian atas dan kanan ada lapisan ekstra \ 0. Jadi yang tersisa hanyalah pembersihan:

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
sumber
Apakah tempat penampungan air Anda bekerja di sekitar sudut interior, jika ada?
mbomb007
@ mbomb007: Ya, karena area tersebut diputar berulang kali, sehingga ia dapat mengikuti koridor yang berliku. Lingkaran berhenti terlalu dini sebelum mengurangi dinding yang sangat tebal adalah satu-satunya kelemahan sejauh yang saya tahu
Ton Hospel
@ mbomb007: Aaaa dan cacat dinding yang tebal sekarang dipecahkan
Ton Hospel
salin-tempelkan solusi Anda apa adanya (tidak menggantikan karakter yang lolos), output hanyalah input dengan semua yang #dilucuti. harap verifikasi sesi bash saya: codepad.org/YbCzB4O4
ardnew
@ardnew: Ups, maaf. Untuk pembaruan terakhir tidak mengecam ulang solusi lengkap, dan saya harus mengganti sementara dengan sampai. Diperbaiki sekarang, Silakan coba lagi
Ton Hospel
4

Javascript, 485 464 427 417 396 390 byte

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

Iya. Saya mencoba. Dan, meskipun saya berada di 485 byte, saya menang karena tidak ada orang lain yang ingin menjawab pertanyaan ini. Jadi, hah!
Dan juga, saya sangat sadar bahwa saya bisa bermain golf ini, saya hanya lelah saat ini ... nah sekarang saya di 396 Terima kasih kepada Conor untuk sebagian besar bermain golf ...: D

Botak Bantha
sumber
1
Nyatakan variabel di dalam untuk loop luar dengany=z=0
Bálint