Remplissez les lacs

19

Étant donné la topographie des terres au format ASCII, déterminez où les lacs iraient et remplissez-les. Supposez une quantité infinie de pluie.

exemple

contribution

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

production

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

L'entrée ne contiendra que des espaces et des #marques. Chaque ligne aura la même longueur. La sortie devrait être le #modèle identique avec des espaces où l'eau s'accumulerait remplie de @marques.

La ligne d'entrée inférieure sera toujours composée de tous les signes #. Il n'y aura pas de trous ou de surplombs dans la terre. Le code le plus court gagne.

Keith Randall
la source
Cela semble un peu facile. Je pense que nous devrions également afficher le nombre d'unités de lac @qui ont été remplies.
mellamokb
1
@mellamokb: Ce serait à peu près un ([char[]]"$a"-eq'@').Countici. Pas trop ajouter. Je suis d'accord pour dire que c'est un peu trop facile, cependant. Cependant, cela ne tombe pas dans le domaine de ce que je dévaloriserais.
Joey
3
En relation avec Stack Overflow: Code Golf: Running Water . L'un des meilleurs de LiraNuna, pensai-je.
dmckee
1
Alors, devons-nous également gérer des cavernes souterraines, qui peuvent avoir de l'air au-dessus du niveau de l'eau comme le puzzle de l'eau courante? Cela rend les choses un peu plus difficiles et je pense que cela devrait certainement être un exemple d'utilisation.
mellamokb
@dmckee: Celui-là n'était pas aussi simple que cela.
Joey

Réponses:

8

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

24 (27):

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

27 (30):

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

Concourt avec le meilleur des deux solutions Perl

asoundmove
la source
#|@serait un caractère plus court
VOUS
2
Vous devez ajouter 3 au nombre pour l'indicateur -r. Vous pouvez couper deux de supprimer les es, et un autre de la suggestion de S.Mark de revenir à 27 cependant.
Nabb
@Nabb thanks, a découvert quelque chose avec l'étiquette vide
asoundmove
J'ai essayé sed auparavant, mais j'ai échoué
Ming-Tang
@Keith, merci pour le prix.
asoundmove
7

Perl, 25

s/# +#/$_=$&;y| |@|;$_/ge
Ming-Tang
la source
J'ai ajouté un nombre de caractères. Veuillez vérifier s'il est réellement correct, car il pourrait avoir besoin d'inclure des indicateurs d'interpréteur ( -ppeut-être?).
Joey
je ne connais pas le langage perl, mais je peux sentir sa puissance :)
Ant's
En fait, il a besoin de `-pe` pour fonctionner sur ma boîte, donc cela devrait être 4 caractères supplémentaires. Ou ne ecompte pas et donc seulement 3 caractères supplémentaires requis?
asoundmove
Pas besoin du e, comme je l'ai mentionné ailleurs, pour les mêmes raisons. :)
Robert P
6

Perl (> = v5.9.5), 24 caractères

Courir avec perl -p:

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

Cela nécessite Perl 5.9.5 ou une version ultérieure pour utiliser l'échappement spécial \K.

yibe
la source
1
Sauf que si Nabb est correct, vous devez compter «-p» comme 3 caractères, ce qui porte votre total à 27. Et cela nécessite en fait «-pe . I don't know the full rules about flags, so not sure the e».
asoundmove
N'aurait pas réellement besoin du e, si vous appuyez simplement sur Entrée et le saisissez ensuite, ou placez le code dans un fichier et exécutez-le. Donc -e n'est pas vraiment nécessaire. :)
Robert P
3

Windows PowerShell, 36 74 138

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

Rétine , 10 octets

La rétine est (beaucoup) plus récente que ce défi. Mais cette solution est trop soignée pour ne pas la poster:

T` `@`#.*#

Essayez-le en ligne.

Il s'agit simplement d'une étape de translittération qui remplace les espaces par @, mais l'opération est limitée aux correspondances de #.*#, c'est-à-dire aux personnages qui sont entourés de terres des deux côtés.

Martin Ender
la source
1

Ruby 1.8, 30 caractères

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

Si quelqu'un a une idée pourquoi cela ne fonctionne pas dans Ruby 1.9 (testé avec 1.9.2p0 et 1.9.2p204), même si la documentation dit que cela devrait fonctionner , faites le moi savoir!

Ventero
la source
C'est vraiment bizarre, l'ajout $_=$_.au début de la deuxième ligne le fait fonctionner en 1.9.2 donc c'est quelque chose à voir avec Kernel.gsub. Rubinius échoue également sans ajouter explicitement $_.
Nemo157
Selon le journal NEWS 1.9.1, le noyau # getc, #gsub, #sub sont obsolètes.
VOUS
1
Je pense que vous pouvez compter cela comme 30 (27 + 3 pour avoir besoin du -pdrapeau). Le hash-bash et le nom de l'interpréteur ne comptent pas.
Caleb
1

Python, 95 92 octets

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

05AB1E , 17 16 octets

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

Essayez-le en ligne.

Explication:

|            # 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
la source
0

Javascript, 107 octets

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

Non golfé:

var f = function(x) {
    return x.replace(/# +#/g, function(x){
        return "#" + new Array(x.length - 1).join("@") + "#";
    })
};
BobTheAwesome
la source
Je vous recommande (1) de publier une version normalement formatée de votre réponse afin qu'elle soit plus facile à lire et à suivre et (2) d'examiner ES6 ... cela pourrait vous faire économiser beaucoup de caractères avec vos fonctions.
SirPython
Je publierai une version normale, mais je ne suis pas une personne de type ES6.
BobTheAwesome
@BobTheAwesome Pourquoi venez-vous de suggérer cette modification?
Tim
Oh mon Dieu, j'essayais de corriger l'erreur du cas de test, mais j'ai cette extension activée dans Chrome, si vous connaissez xkcd. Désolé pour ça.
BobTheAwesome
Outre les éléments ES6: vous n'avez pas besoin d'espace après la virgule, vous n'avez pas besoin d'espace après la seconde return, et vous pouvez supprimer les deux points-virgules, et cela peut être simplement function f(x)...ouf=function(x)...
Zacharý
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
la source
0

Pip , 15 octets

aR:`#.*#`_TRs'@

Prend l'entrée sous forme de chaîne multiligne via un argument de ligne de commande: Essayez-le en ligne! (Alternativement, spécifiez les -rnindicateurs et changez le premier aen g, et vous pouvez donner votre entrée via stdin: essayez-le en ligne! )

Même idée que la réponse Retina: remplacer chaque correspondance de l'expression régulière #.*#par le résultat de la translittération de l'espace @dans la correspondance. Pip ne peut pas égaler la gravité de Retina pour un problème de regex pur - mais ce n'est pas tous les jours que vous pouvez nouer avec Jelly, après tout.

DLosc
la source