Що оточує


18

Я завжди хотів оточити якийсь текст за допомогою #s, але у мене виникають труднощі з'ясувати, чим я оточував, у цьому виклику ви будете писати програму, щоб зробити саме це

Приклади

Введення / виходи розділені новим рядком.

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

Спец

  • #s - це те, що "оточує" блок тексту
  • # завжди будуть примикати один до одного (у тому числі по діагоналі)
  • # завжди утворюватиме закриту форму
  • Буде лише одна #форма
  • У разі увігнутої форми отвори слід заповнити пробілами.
  • Білий простір повинен бути збережений у висновку

спочатку я був схожий на .. просто вийміть #і ось ви йдете ... а потім стало важко.
Лисий Бантха

У мене виникають проблеми з отриманням вводу в JavaScript та розщепленням нового рядка ... як я повинен отримати введення? чи може вона бути відформатована \nпісля кожного рядка введення та передана як парам-параметр функції моїй програмі чи що?
Лисий Банта

1
Що таке набір дійсних символів введення?
Тон Євангелія

Чи є помилка на виході прикладу MN ? Його висновок складається лише з оточеного тексту _M_\n___N(використовуючи підкреслення замість пробілів через проблеми з форматуванням), тоді як у прикладах abc та Codego вихід також включає пробіл, де у введенні є #s. Якщо повинен друкуватися лише текст, оточений #s, то вихід прикладу abc повинен бути _a_\n_b_c_(замість __a_\n_b_c), а вихід прикладу Codego повинен бути Co\nde\n_go(замість C___o\nd___e\n__go).
епідемія

@epidemian ах, приємний улов. Я зафіксував MNприклад. як не повинно було бути зайвого місця після М.
Downgoat

Відповіді:


6

Perl, 144 138 132 129 128 127 126 124 байт

Включає +2 для -p0

Код передбачає \0, що не є дійсним символом введення (принаймні, всередині #).

Запустити з введенням 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;#; 

Код працює як є, але замінить \0і \nна їх буквальну версію для заявленої оцінки. Зауважте, що в кінці рядка є пробіл . Код замислюється занадто багато разів, тому вам, можливо, доведеться почекати 30 секунд або близько того, щоб вивести.

Пояснення

Я збираюся зробити заливку з \0зупиняв #ззовні в ортогональних напрямках. Після цього я відріжу #сторони і заміню все, що залишилося пробілами. Щоб уникнути обробки всіх напрямків на затопі, я неодноразово повертатимуть цільову область та лише заливку справа наліво

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

На даний момент, наприклад

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

буде замінено:

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

В основному всі стовпці та рядки, що не межують з внутрішньою стороною, були відрізані. Будь-які зовнішні символи були замінені на \ 0. Угорі та праворуч є додатковий шар \ 0. Отже, все, що залишилося - це прибирання:

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

Чи працюють ваші заливи за внутрішніми куточками, якщо такі були?
mbomb007

@ mbomb007: Так, оскільки область неодноразово повертається, тому вона може слідувати будь-яким закрученим коридорам. Петля, яка зупиняється занадто рано, перш ніж зменшити дуже товсті стіни, є єдиним недоліком, наскільки я знаю
Тон Євангелія

@ mbomb007: Аааа та дефект товстої стіни вирішено
Тон Євангелія

копіюючи вставлення вашого рішення як є (не заміняючи відхилених символів), вихід - це лише вхід з усіма #позбавленими. будь ласка, перевірте мій баш-сеанс: codepad.org/YbCzB4O4
ardnew

@ardnew: На жаль, вибачте. Для останнього оновлення не відновив повне рішення, і я повинен був замінити час на до. Виправлено зараз. Повторіть спробу
Тон Євангелія

4

Javascript, 485 464 427 417 396 390 байт

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

Так. Я намагався. І хоча я набрав 485 байт, я перемагаю, тому що ніхто більше не відчував, як відповісти на це питання. Отже, га!
А також, я добре знаю, що я могла би навантажувати ці вантажі, я просто втомилася на даний момент ... ну зараз я на 396 Завдяки Конору за більшу частину гольфу ...: D


1
Оголосіть змінні всередині циклів для циклів зовні зy=z=0
Bálint
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.