Что окружает


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 это то, что «окружает» блок текста
  • # всегда будет рядом друг с другом (в том числе по диагонали)
  • # всегда будет формировать замкнутую форму
  • Там будет только одна #форма
  • В случае вогнутой формы отверстия должны быть заполнены пробелами.
  • Пробелы должны быть сохранены в выводе

Сначала я был как ... просто вынуть #s и там вы идете ... а потом стало трудно.
Лысая банта

У меня проблемы с получением ввода в javascript и разделением по новой строке ... как мне получить ввод? может ли он быть отформатирован \nпосле каждой строки ввода и передаваться в качестве параметра функции моей программе или как?
Лысая банта

1
Что такое набор допустимых символов ввода?
Тон Хоспел

Есть ли ошибка на выходе примера MN ? Его выходные данные состоят только из окруженного текста _M_\n___N(с использованием подчеркивания вместо пробелов из-за проблем с форматированием), в то время как в примерах abc и Codego выходные данные также включают пробельные символы, где # были во входных данных. Если должен быть напечатан только текст, окруженный символом #, то вывод примера 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: А-а-а-а, теперь проблема с толстыми стенами решена
Тон Хоспел

скопируйте ваше решение как есть (не заменяя экранированные символы), вывод - это просто ввод со всеми #разделами. пожалуйста, проверьте мой сеанс bash: 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
Объявите переменные внутри циклов for снаружи с помощьюy=z=0
Bálint
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.