Preencha os lagos

19

Dada a topografia da terra no formato de imagem ASCII, descubra para onde os lagos iriam e os preencha. Assuma uma quantidade infinita de chuva.

exemplo

entrada

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

resultado

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

A entrada conterá apenas espaços e #marcas. Cada linha terá o mesmo comprimento. A saída deve ser o #padrão idêntico aos espaços onde a água se acumularia preenchida com @marcas.

A linha de entrada inferior sempre terá todas as marcas #. Não haverá buracos ou saliências na terra. O menor código vence.

Keith Randall
fonte
Isso parece um pouco fácil. Acho que também deve ter para exibir o número de unidades lago @que foram preenchidos.
mellamokb
11
@mellamokb: Isso seria aproximadamente um ([char[]]"$a"-eq'@').Countaqui. Não é muito adicionar. Mas concordamos que isso é um pouco fácil demais. No entanto, não cai no reino do que eu votaria.
Joey
3
Relacionado ao Stack Overflow: Code Golf: Running Water . Um dos melhores do LiraNuna, pensei.
dmckee
11
Então também precisamos lidar com cavernas subterrâneas, que podem ter ar acima do nível da água, como o quebra-cabeça Água Corrente? Isso torna as coisas um pouco mais desafiadoras e acho que deve ser definitivamente um exemplo de caso de uso.
Mellamokb
@dmckee: Esse não foi tão fácil quanto isso.
Joey

Respostas:

8

sed -r, 27 24 (27 com -r)

24 (27):

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

27 (30):

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

Compete com a melhor das duas soluções perl

asoundmove
fonte
#|@seria um char mais curto
VOCÊ
2
Você deve adicionar 3 à contagem do sinalizador -r. Você pode cortar dois removendo os es e outro da sugestão de S. Mark para voltar para 27.
Nabb
Graças @Nabb, descobriu algo com a etiqueta vazia
asoundmove
Tentei sed antes, mas falhou
Ming-Tang
@ Keith, obrigado pelo prêmio.
asoundmove
7

Perl, 25

s/# +#/$_=$&;y| |@|;$_/ge
Ming-Tang
fonte
Eu adicionei uma contagem de caracteres. Veja se está realmente correto, pois pode precisar incluir alguns sinalizadores de intérprete ( -ptalvez?).
Joey
Eu não sei linguagem perl, mas eu posso sentir seu poder :)
de Formiga
Na verdade, ele precisa do `-pe` para funcionar na minha caixa, de modo que devem ser 4 caracteres adicionais. Ou isso enão conta e, portanto, são necessários apenas 3 caracteres adicionais?
asoundmove
Não precisa do e, como mencionei em outros lugares, pelas mesmas razões. :)
Robert P
6

Perl (> = v5.9.5), 24 caracteres

Corra com perl -p:

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

Isso requer o Perl 5.9.5 ou posterior para usar a fuga especial \K.

yibe
fonte
11
Exceto que, se o Nabb estiver correto, você precisará contar `-p` como 3 caracteres, elevando o total para 27. E, na verdade, isso exige . I don't know the full rules about flags, so not sure the contagens do` -pe e` .
Asoundmove 13/05
Na verdade, não seria necessário o e, se você simplesmente pressionar enter e digitar posteriormente, ou colocar o código em um arquivo e executá-lo. Então -e não é realmente necessário. :)
Robert P
3

Windows PowerShell, 36 74 138

$input-replace'(?<!^ *) (?! *$)','@'
Joey
fonte
2

Retina , 10 bytes

A retina é (muito) mais nova que esse desafio. Mas esta solução é muito legal para não publicá-la:

T` `@`#.*#

Experimente online.

Este é simplesmente um estágio de transliteração que substitui os espaços @, mas a operação é restrita a correspondências de #.*#, ou seja, caracteres cercados por terra dos dois lados.

Martin Ender
fonte
1

Ruby 1.8, 30 caracteres

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

Se alguém tiver uma idéia de por que isso não funciona no Ruby 1.9 (testado com 1.9.2p0 e 1.9.2p204), mesmo que a documentação diga que deve funcionar , me avise!

Ventero
fonte
Isso é realmente estranho, adicionar $_=$_.o início da segunda linha faz com que funcione na versão 1.9.2, por isso é algo a ver Kernel.gsub. Rubinius também falha sem adicionar explicitamente $_.
Nemo157 13/05
De acordo com 1.9.1 log NEWS, Kernel # getc, #gsub, #sub estão obsoletos.
VOCÊ
11
Eu acho que você pode contar isso como 30 (27 + 3 por precisar da -pbandeira). O hash-bash e o nome do intérprete não contam.
Caleb
1

Python, 95 92 bytes

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

05AB1E , 17 16 bytes

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

Experimente online.

Explicação:

|            # 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
Kevin Cruijssen
fonte
0

Javascript, 107 bytes

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("@") + "#";
    })
};
BobTheAwesome
fonte
Eu recomendo que você (1) publique uma versão normalmente formatada da sua resposta, para que seja mais fácil ler e acompanhar e (2) examine o ES6 ... isso pode poupar muitos caracteres com suas funções.
SirPython
Vou postar uma versão normal, mas não sou do tipo ES6.
BobTheAwesome
@BobTheAwesome Por que você acabou de sugerir esta edição?
Tim
Oh meu Deus, eu estava tentando corrigir o erro do caso de teste, mas tenho essa extensão ativada no chrome, se você conhece o xkcd. Me desculpe por isso.
BobTheAwesome
Além do material ES6: você não precisa o espaço após a vírgula, você não precisa do espaço após o segundo return, e você pode remover os dois pontos e vírgulas, e pode apenas ser function f(x)...ouf=function(x)...
Zachary
0

Python, 108 106 92 bytes

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

Pip , 15 bytes

aR:`#.*#`_TRs'@

Recebe a entrada como uma cadeia de linhas múltiplas através do argumento da linha de comando: Experimente online! (Como alternativa, especifique os -rnsinalizadores e altere o primeiro apara g, e você pode fornecer informações via stdin: Experimente online! )

A mesma idéia da resposta da Retina: substitua todas as correspondências da expressão regular #.*#pelo resultado do espaço de transliteração @na correspondência. Pip não pode igualar a discrepância de Retina por um problema de regex puro - mas não é todo dia que você pode amarrar Jelly, afinal.

DLosc
fonte