Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Given the topology of land in ASCII picture format, figure out where lakes would go and fill them in. Assume an infinite amount of rain.

example

input

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

output

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

The input will contain only spaces and # marks. Each line will be the same length. The output should be the identical # pattern with spaces where water would accumulate filled in with @ marks.

The bottom input row will always be all # marks. There will be no holes or overhangs in the land. Shortest code wins.

share|improve this question
    
This seems a bit easy. I think we should also have to display the number of lake units @ that were filled in. –  mellamokb May 12 '11 at 20:53
1  
@mellamokb: This would be roughly a ([char[]]"$a"-eq'@').Count here. Not that much too add. Agreed on this being a little too easy, though. Doesn't fall into the realm of what I'd downvote, though. –  Joey May 12 '11 at 20:55
1  
Related on Stack Overflow: Code Golf: Running Water. One of LiraNuna's better one, I thought. –  dmckee May 12 '11 at 21:41
1  
So do we also have to handle underground caverns, which may have air above the water level like the Running Water puzzle? That makes things a little more challenging and I think should definitely be an example use case. –  mellamokb May 12 '11 at 21:45
    
@dmckee: That one wasn't as easy as this though. –  Joey May 12 '11 at 21:45
show 3 more comments

7 Answers 7

up vote 7 down vote accepted

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

24 (27):

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

27 (30):

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

Competes with the better of the two perl solutions

share|improve this answer
    
#|@ would be one char shorter –  YOU May 13 '11 at 6:34
2  
You should add 3 to the count for the -r flag. You can cut off two from removing the es, and another from S.Mark's suggestion to get back to 27 though. –  Nabb May 13 '11 at 7:25
    
@Nabb thanks, discovered something with the empty label –  asoundmove May 13 '11 at 12:36
    
I tried sed before, but failed –  SHiNKiROU May 13 '11 at 17:45
    
@Keith, thanks for the award. –  asoundmove May 21 '11 at 5:09
add comment

Perl, 25

s/# +#/$_=$&;y| |@|;$_/ge
share|improve this answer
    
I added a character count. Please look whether it's actually correct, as it might need to include some interpreter flags (-p maybe?). –  Joey May 13 '11 at 7:25
    
i dont know perl language, but i can feel its power :) –  Ant's May 13 '11 at 13:33
    
Actually it needs ` -pe` to function on my box, so that should be an additional 4 chars. Or does the e not count and thus only 3 additional chars required? –  asoundmove May 13 '11 at 23:24
    
Don't need the e, like I mentioned elsewhere, for the same reasons. :) –  Robert P May 26 '11 at 17:55
add comment

Perl (>= v5.9.5), 24 chars

Run with perl -p:

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

This requires Perl 5.9.5 or later to use the special escape \K.

share|improve this answer
1  
Except that if Nabb is correct, you need to count ` -p` as 3 chars, bringing your total to 27. And it actually requires ` -pe`. I don't know the full rules about flags, so not sure the e counts. –  asoundmove May 13 '11 at 23:27
    
Wouldn't actually need the e, if you simply hit enter and type it in afterwards, or put the code in a file and run it. So -e isn't really needed. :) –  Robert P May 26 '11 at 17:52
add comment

Windows PowerShell, 36 74 138

$input-replace'(?<!^ *) (?! *$)','@'
share|improve this answer
add comment

Ruby 1.8, 30 characters

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

If anyone has an idea why this doesn't work in Ruby 1.9 (tested with 1.9.2p0 and 1.9.2p204), even though the documentation says it should work, let me know!

share|improve this answer
    
That's really weird, adding in $_=$_. to the start of the second line makes it work in 1.9.2 so it's something to do with Kernel.gsub. Rubinius also fails without explicitly adding $_. –  Nemo157 May 13 '11 at 6:51
    
According to 1.9.1 NEWS log, Kernel#getc, #gsub, #sub are deprecated. –  YOU May 13 '11 at 7:25
1  
I think you can count this as 30 (27 + 3 for needing the -p flag). The hash-bash and name of the interpreter doesn't count. –  Caleb May 18 '11 at 10:55
add comment

Python 92 95

for s in S.split('\n'):b=s.find('#');e=s.rfind('#');print s[:b]+s[b:e].replace(' ','@')+s[e:]
share|improve this answer
add comment

Python 92 106 108

import re
n=1
while n: S,n=re.subn('# +#',lambda m:'#'+'@'*len(m.group(0)[2:])+'#',S)
print S
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.