Water held in a hexagonal rod scuplture

Python 2, 222 bytes

import sys
y=h=v=0;B={}
for l in sys.stdin:
 z=y;y+=2j
 while l:
    if"0"<l:B[z]=int(l[:2])
    l=l[2:];z+=1
while B:C=B;B={b:B[b]for b in B if(h<B[b])+sum(3>abs(c-b)for c in B)/7};a=C==B;h+=a;v+=a*sum(h>B[b]for b in B)
print v

Reads input through STDIN and writes the result to STDOUT.

Explanation

We start at zero and incrementally increase the water level as follows: Suppose that the water level is h, and we want to add 1 centimeter of water. We'll call hexagons of height h or less, ones that are about to go (or already are) underwater, "submerged." The water will spill through any submerged hexagon that isn't surrounded by six neighbors. We eliminate all such hexagons; of course, now some other submerged hexagons might have less than six neighbors, and they need to be eliminated as well. We continue in this fashion until convergence, i.e., until all remaining submerged hexagons have exactly six neighbors. At this point we add the number of submerged hexagons (the gained water volume) to the total count, and increment the water level.

Eventually, all the hexagons will have been eliminated and we halt.


Ruby 299

f=->i{s={}
l=i.lines
y=0
l.map{|r|x=0
r.scan(/../){s[[x,y]]=[v=$&.to_i,v<1?0:99];x+=1}
y+=1}
loop{break if s.map{|c,r|x,y=c
m = [[-1,-1],[1,-1],[-2,0],[2,0],[1,-1],[1,1]].map{|w,z|s[[x+w,y+z]]}.map{|n|n ?n[0]+n[1]:0}.min
r[1]=[0,m-r[0]].max if r[0]+r[1]>m&&r[1]>0}.none?}
s.map{|c,r|r[1]}.reduce :+}

Brief description of the algorithm:

  • parses the input, and for each rod saves a two-element array of the form [rod_height, water_height]
  • rods are placed in a hash and indexed by their x,y coordinates
  • the water leaking part takes into account the rod/water heights of the immediate neighbors

A slightly more readable version is available here: http://ideone.com/cWkamV

Run the golfed version online with tests: http://ideone.com/3SFjPN