Заполните озера


19

Учитывая топографию земли в формате изображения ASCII, определите, куда озера пойдут, и заполните их. Предположите бесконечное количество осадков.

пример

вход

         #               
         ##              
      # ####             
#    #########           
##  ###########          
## #############   ####  
## ##############  ##### 
################# #######
#########################
#########################

выход

         #               
         ##              
      #@####             
#@@@@#########           
##@@###########          
##@#############@@@####  
##@##############@@##### 
#################@#######
#########################
#########################

Входные данные будут содержать только пробелы и #метки. Каждая строка будет одинаковой длины. На выходе должен быть идентичный #шаблон с пространствами, в которых будет скапливаться вода, заполненными @отметками.

В нижней строке ввода всегда будут все # отметки. На земле не будет дыр или свесов. Самый короткий код выигрывает.


Это кажется немного легким. Я думаю, что мы должны также отобразить количество единиц озера, @которые были заполнены.
mellamokb

1
@mellamokb: Это было бы примерно ([char[]]"$a"-eq'@').Countздесь. Не так уж много добавить. Договорились, что это слишком легко. Впрочем, это не относится к тому, что я бы понизил.
Джои

3
Связано с переполнением стека: Код Гольф: Вода . Я подумала, что одна из лучших LiraNuna
dmckee

1
Так нужно ли нам обращаться с подземными пещерами, в которых может быть воздух над уровнем воды, как в пазле «Бегущая вода»? Это делает вещи немного более сложными, и я думаю, что это определенно пример использования.
mellamokb

@dmckee: Хотя это было не так просто.
Джои

Ответы:


8

сед-р, 27 24 (27 с -r)

24 (27):

:;s/(#|@) ( *#)/\1@\2/;t

27 (30):

:e;s/([#@]) ( *#)/\1@\2/;te

Конкурирует с лучшими из двух решений Perl


#|@будет на один символ короче
ВЫ

2
Вы должны добавить 3 к счетчику флага -r. Вы можете отрезать два от удаления es, а другой от предложения С.Марка, чтобы вернуться к 27, хотя.
Набб

@Nabb спасибо, обнаружил что-то с пустым ярлыком
asoundmove

Я пробовал sed раньше, но не получилось
Ming-Tang

@Keith, спасибо за награду.
asoundmove

7

Perl, 25

s/# +#/$_=$&;y| |@|;$_/ge

Я добавил количество символов. Пожалуйста, посмотрите, действительно ли это правильно, так как может потребоваться включить некоторые флаги интерпретатора ( -pвозможно?).
Джои

я не знаю языка Perl, но чувствую его силу :)
Ant's

На самом деле для работы на моем боксе требуется `-pe`, так что должно быть еще 4 символа. Или eне считается и, следовательно, требуется только 3 дополнительных символа?
asoundmove

Не нужно, как я упоминал в другом месте, по тем же причинам. :)
Роберт П

6

Perl (> = v5.9.5), 24 символа

Запустить с perl -p:

1while s/#.*\K (?=\S)/@/

Для этого требуется Perl 5.9.5 или новее, чтобы использовать специальный escape \K.


1
За исключением того, что, если Nabb верен, вам нужно посчитать `-p` как 3 символа, доведя итоговое значение до 27. И для этого на самом деле требуются значения` -pe . I don't know the full rules about flags, so not sure the e`.
asoundmove

На самом деле не нужен e, если вы просто нажмете Enter и введите его впоследствии, или поместите код в файл и запустите его. Так что мы не очень нужны. :)
Роберт П


2

Сетчатка , 10 байт

Сетчатка (намного) новее, чем этот вызов. Но это решение слишком аккуратно, чтобы не публиковать его:

T` `@`#.*#

Попробуйте онлайн.

Это просто этап транслитерации, который заменяет пробелы на @, но операция ограничивается совпадениями #.*#, то есть символами, которые окружены землей с обеих сторон.


1

Ruby 1.8, 30 символов

#!ruby -p
gsub(/# +#/){$&.tr" ","@"}

Если у кого-то есть идея, почему это не работает в Ruby 1.9 (протестировано с 1.9.2p0 и 1.9.2p204), хотя в документации сказано, что это должно работать , дайте мне знать!


Это действительно странно, добавление $_=$_.к началу второй строки заставляет его работать в 1.9.2, так что это как-то связано Kernel.gsub. Рубиниус также терпит неудачу без явного добавления $_.
Nemo157

Согласно журналу 1.9.1 NEWS, Kernel # getc, #gsub, #sub устарели.
ВЫ

1
Я думаю, что вы можете считать это как 30 (27 + 3 для нужд -pфлага). Hash-bash и имя интерпретатора не учитываются.
Калеб

1

Python, 95 92 байта

for s in S.split('\n'):b=s.find('#');e=s.rfind('#');print s[:b]+s[b:e].replace(' ','@')+s[e:]

1

05AB1E , 17 16 байт

|εγć?D¨ð'@:sθJJ,

Попробуйте онлайн.

Объяснение:

|            # Take all input-lines as list
 ε           # For each line:
  γ          #  Split the line into chunks of consecutive equal characters
             #   i.e. " ##   # " → [' ','##','   ','#',' ']
   ć         #  Split into head and the rest of the list
             #   i.e. [' ','##','   ','#',' '] → ['##','   ','#',' '] and ' '
    ?        #  Print this head
   D         #  Duplicate the rest of the list
    ¨        #  Remove the last element
             #   i.e. ['##','   ','#',' '] → ['##','   ','#']
     ð'@:    #  Replace every space with a "@"
             #   i.e. ['##','   ','#'] → ['##','@@@','#']
     sθ      #  Swap so the duplicated list is at the top, and take the last item as is
             #   i.e. ['##','   ','#',' '] → ' '
         JJ  #  Join the lists and individual items in the list together to a single string
             #   i.e. ['##','@@@','#'] and ' ' → "##@@@# "
           , #  Print with trailing new-line

0

Javascript, 107 байт

var f=function(x){return x.replace(/# +#/g, function(x){return "#"+new Array(x.length-1).join("@")+"#";})};

Ungolfed:

var f = function(x) {
    return x.replace(/# +#/g, function(x){
        return "#" + new Array(x.length - 1).join("@") + "#";
    })
};

Я рекомендую вам (1) опубликовать нормально отформатированную версию вашего ответа, чтобы было легче читать и следовать, и (2) изучить ES6 ... это может сэкономить вам много символов с вашими функциями.
SirPython

Я выложу нормальную версию, но я не человек типа ES6.
BobTheAwesome

@BobTheAwesome Почему вы только что предложили это редактирование?
Тим

О боже, я пытался исправить ошибку в тестовом примере, но у меня включено это расширение в chrome, если вы знаете xkcd. Прости за это.
BobTheAwesome

Помимо материала ES6: вам не нужно пространство после запятой, вам не нужно пространство после второй return, и вы можете удалить две точки с запятой, и это может быть просто function f(x)...илиf=function(x)...
Zacharý

0

Python, 108 106 92 байта

import re
n=1
while n: S,n=re.subn('# +#',lambda m:'#'+'@'*len(m.group(0)[2:])+'#',S)
print S


0

Пип , 15 байт

aR:`#.*#`_TRs'@

Принимает ввод в виде многострочной строки через аргумент командной строки: попробуйте онлайн! (В качестве альтернативы укажите -rnфлаги и измените первый aна g, и вы можете вводить данные через stdin: попробуйте онлайн! )

Та же идея, что и в ответе Retina: заменять каждое совпадение регулярного выражения #.*#на результат транслитерации пространства @в совпадении. Пип не может сравниться с краткостью Ретины из-за проблем с регулярным выражением - но ведь не каждый день ты можешь связать себя с Джелли.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.