Etrafta ne var


18

Her zaman bazı metinleri çevrelemek istedim # s , ama ne çevremde bulmakta sorun var bu yüzden bu meydan okuma sadece bunu yapmak için bir program yazacak

Örnekler

Giriş / Çıkışlar bir satırsonu ile ayrılır.

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

  • #bir metin bloğunu "çevreleyen" ler
  • # her zaman birbirine bitişik olacaktır (çapraz olarak dahil)
  • # her zaman kapalı bir şekil oluşturur
  • Sadece bir #şekil olacak
  • İçbükey bir şekil olması durumunda delikler boşluklarla doldurulmalıdır.
  • Çıktıda boşluk korunmalıdır

ilk başta .. sadece #s çıkarın ve işte gidiyorsun ... ve sonra zorlaştı.
Bald Bantha

Javascript giriş almak ve newline tarafından bölme sorun yaşıyorum ... nasıl girdi almak zorunda? ile biçimlendirilebilir mi\nher girdi satırından sonra ve programıma bir işlev parametresi olarak geçirilebilir mi veya ne olabilir?
Bald Bantha

1
Geçerli giriş karakterleri kümesi nedir?
Ton Hospel

MN örneğinin çıktısında bir hata var mı ? Çıktısı yalnızca çevrelenen metinden oluşur ( _M_\n___Nbiçimlendirme sorunları nedeniyle boşluklar yerine alt çizgiler kullanılarak ), abc ve Codego örneklerinde ise çıktıda #s girdisinin bulunduğu boşluk da bulunur. Yalnızca #s ile çevrili metin yazdırılacaksa, abc örneğinin çıktısı _a_\n_b_c_(yerine __a_\n_b_c) ve Codego örneğinin çıktısı Co\nde\n_go(yerine C___o\nd___e\n__go) olmalıdır.
epidemya

@epidemian ah, güzel yakalama. MNÖrneği düzelttim .
M.'den

Yanıtlar:


6

Perl, 144 138 132 129 128 127 126 124 bayt

İçin +2 içerir -p0

Kod \0, geçerli bir giriş karakteri (en azından içinde #) olduğunu varsayar .

STDIN üzerindeki giriş ile çalıştırın:

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 olarak çalışıyor, ancak yerini \0ve \niddia puan için onların literal versiyonlarını tarafından. Bir boşluk olduğuna dikkat edinSatırın sonunda . Kod çok fazla döngü yapıyor, bu nedenle çıktı için 30 saniye beklemeniz gerekebilir.

açıklama

Tarafından \0durdurulmuş ile bir taşkın dolgu yapacağım#Ortogonal yönlerde dışarıdan . Bundan sonra #kenarları kesip boşluklarla kalanları değiştireceğim. Taşkın dolgusundaki tüm yönleri ele almaktan kaçınmak için hedef alanı tekrar tekrar döndüreceğim ve sadece sağdan sola taşkın dolgu

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

Bu noktada örn.

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

ile değiştirilecek:

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

Temel olarak, doğrudan iç kısmı çevreleyen tüm sütunlar ve satırlar dilimlenmiştir. Kalan tüm dış karakterler \ 0 ile değiştirildi. Üstte ve sağda fazladan bir \ 0 katmanı var. Yani geriye kalan tek şey temizlik:

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

Taşkın dolgularınız varsa iç köşelerde çalışıyor mu?
mbomb007

@ mbomb007: Evet, alan tekrar tekrar döndürüldüğünden, herhangi bir kıvrımlı koridoru takip edebiliyor. Çok kalın duvarları azaltmadan önce çok erken duran döngü, bildiğim kadarıyla tek kusur
Ton Hospel

@ mbomb007: Aaaaand kalın duvar kusuru şimdi çözüldü
Ton Hospel

çözümünüzü olduğu gibi kopyalayıp yapıştırarak (kaçan karakterlerin yerini almaz), çıktı yalnızca #soyulmuş olan girdidir . lütfen bash oturumumu doğrulayın: codepad.org/YbCzB4O4
ardnew

@ardnew: Hata! Son güncelleme tam çözüm için cevap vermedi ve ben bir zamana kadar değiştirmeliydim. Şimdi düzeltildi, lütfen tekrar deneyin
Ton Hospel

4

Javascript, 4854644417417396390 bayt

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

Evet. Denedim. Ve 485 baytta olmama rağmen kazanıyorum çünkü kimse bu soruyu cevaplamak istemedi. Yani, hah!
Ve ayrıca, bu yükleri golf oynayabileceğimin bilincindeyim, şu anda yorgunum ... şimdi de 396'dayım Golfün çoğu için Conor'a teşekkürler ...: D


1
Dışında döngüler için değişkenleriy=z=0
Bálint
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.