# http://c...content-available-to-author-only...e.com/questions/47229/water-held-in-a-hexagonal-rod-scuplture
require 'minitest/autorun'
require 'pp'
Rod = Struct.new :x,:y,:height,:water_height,:neighbors do
def to_s
"(#{x},#{y})->#{height}"
end
def total_height
height + water_height
end
end
f=->input{
#parse input
list = []
l = input.lines.to_a
(0...l.size).map do |y|
x=-1
list += l[y].scan(/../).map{|v| Rod.new x=x+1, y, v.to_i, v.to_i<1?0:99}
end
empty_rod = Rod.new(0,0,0,0)
find_rod_by_coords=->x,y{list.find{ |r| r.x==x && r.y==y } || empty_rod}
# populate the neighbors of each rod
list.each do |rod|
neighbor_coord_offsets = [[-1,-1],[1,-1],[-2,0],[2,0],[1,-1],[1,1]]
rod.neighbors = neighbor_coord_offsets.map{|w,z| find_rod_by_coords[rod.x+w,rod.y+z]}
end
# let the water leak...
changed = 1
adjust_water=->rod{
m = rod.neighbors.map(&:total_height).min
if rod.total_height > m && rod.water_height > 0
rod.water_height = [0,m-rod.height].max
changed = 1
end
}
(changed=!0
list.map{|rod| adjust_water[rod]}
)while changed
# ...and return the result
list.map(&:water_height).reduce :+
}
describe '#f' do
it 'passes test case #1' do
input = <<-EOS
04 04
04 01 03
04 04
EOS
assert_equal 2, f[input]
end
it 'passes test case #2' do
input = <<-EOS
55 34 45 66
33 21 27
23 12 01 77
36 31 74
EOS
assert_equal 35, f[input]
end
it 'passes test case #3' do
input = <<-EOS
35 36 77 22 23 32 54 24
33 07 02 04 21 54 07 07 07 76
20 04 07 07 01 20 54 11 81 81 07 76
20 67 67 22 07 01 78 54 07 81 07 81 09 76
20 67 07 67 22 22 07 44 55 54 07 81 07 07 61 07 20
67 57 50 50 07 07 14 03 02 15 81 99 91 07 81 04
67 07 50 50 87 39 45 41 34 81 07 07 89 07 81 79
67 07 50 50 07 07 07 27 07 27 81 07 07 79 81 78
20 67 67 07 07 07 07 99 33 46 02 81 07 07 81 01 20
33 07 07 01 05 01 92 20 02 81 07 81 15 32
22 07 20 20 07 20 63 02 80 81 15 32
45 20 01 20 39 20 15 07 15 32
23 20 20 29 43 21 18 41 20 66 66 43 21
90 99 47 07 20
50 20 02 48
70 56 20
90
EOS
assert_equal 1432, f[input]
end
end
IyBodHRwOi8vYy4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4uZS5jb20vcXVlc3Rpb25zLzQ3MjI5L3dhdGVyLWhlbGQtaW4tYS1oZXhhZ29uYWwtcm9kLXNjdXBsdHVyZQpyZXF1aXJlICdtaW5pdGVzdC9hdXRvcnVuJwpyZXF1aXJlICdwcCcKClJvZCA9IFN0cnVjdC5uZXcgOngsOnksOmhlaWdodCw6d2F0ZXJfaGVpZ2h0LDpuZWlnaGJvcnMgZG8KICBkZWYgdG9fcwogICAgIigje3h9LCN7eX0pLT4je2hlaWdodH0iCiAgZW5kCgogIGRlZiB0b3RhbF9oZWlnaHQKICAgIGhlaWdodCArIHdhdGVyX2hlaWdodAogIGVuZAplbmQKCmY9LT5pbnB1dHsKCiAgI3BhcnNlIGlucHV0CiAgbGlzdCA9IFtdCiAgbCA9IGlucHV0LmxpbmVzLnRvX2EKICAoMC4uLmwuc2l6ZSkubWFwIGRvIHx5fAogICAgeD0tMSAgICAgIAogICAgbGlzdCArPSBsW3ldLnNjYW4oLy4uLykubWFwe3x2fCBSb2QubmV3IHg9eCsxLCB5LCB2LnRvX2ksIHYudG9faTwxPzA6OTl9CiAgZW5kIAoKICBlbXB0eV9yb2QgPSBSb2QubmV3KDAsMCwwLDApCiAgZmluZF9yb2RfYnlfY29vcmRzPS0+eCx5e2xpc3QuZmluZHsgfHJ8IHIueD09eCAmJiByLnk9PXkgfSB8fCBlbXB0eV9yb2R9CgogICMgcG9wdWxhdGUgdGhlIG5laWdoYm9ycyBvZiBlYWNoIHJvZAogIGxpc3QuZWFjaCBkbyB8cm9kfAogICAgbmVpZ2hib3JfY29vcmRfb2Zmc2V0cyA9IFtbLTEsLTFdLFsxLC0xXSxbLTIsMF0sWzIsMF0sWzEsLTFdLFsxLDFdXQogICAgcm9kLm5laWdoYm9ycyA9IG5laWdoYm9yX2Nvb3JkX29mZnNldHMubWFwe3x3LHp8IGZpbmRfcm9kX2J5X2Nvb3Jkc1tyb2QueCt3LHJvZC55K3pdfQogIGVuZAoKICAjIGxldCB0aGUgd2F0ZXIgbGVhay4uLgogIGNoYW5nZWQgPSAxCgogIGFkanVzdF93YXRlcj0tPnJvZHsKICAgIG0gPSByb2QubmVpZ2hib3JzLm1hcCgmOnRvdGFsX2hlaWdodCkubWluCiAgICBpZiByb2QudG90YWxfaGVpZ2h0ID4gbSAmJiByb2Qud2F0ZXJfaGVpZ2h0ID4gMAogICAgICByb2Qud2F0ZXJfaGVpZ2h0ID0gWzAsbS1yb2QuaGVpZ2h0XS5tYXgKICAgICAgY2hhbmdlZCA9IDEKICAgIGVuZAogIH0KCiAgKGNoYW5nZWQ9ITAKICAgIGxpc3QubWFwe3xyb2R8IGFkanVzdF93YXRlcltyb2RdfQogICl3aGlsZSBjaGFuZ2VkCgogICMgLi4uYW5kIHJldHVybiB0aGUgcmVzdWx0CiAgbGlzdC5tYXAoJjp3YXRlcl9oZWlnaHQpLnJlZHVjZSA6Kwp9CgoKZGVzY3JpYmUgJyNmJyBkbwoKICBpdCAncGFzc2VzIHRlc3QgY2FzZSAjMScgZG8KICAgIGlucHV0ID0gPDwtRU9TCiAgMDQgIDA0CjA0ICAwMSAgMDMKICAwNCAgMDQKRU9TCiAgICAKICAgIGFzc2VydF9lcXVhbCAyLCBmW2lucHV0XQogIGVuZAoKICBpdCAncGFzc2VzIHRlc3QgY2FzZSAjMicgZG8KICAgIGlucHV0ID0gPDwtRU9TCjU1ICAzNCAgNDUgIDY2CiAgMzMgIDIxICAyNwoyMyAgMTIgIDAxICA3NwogIDM2ICAzMSAgNzQKRU9TCgogICAgYXNzZXJ0X2VxdWFsIDM1LCBmW2lucHV0XQogIGVuZAoKCiAgaXQgJ3Bhc3NlcyB0ZXN0IGNhc2UgIzMnIGRvCiAgICBpbnB1dCA9IDw8LUVPUwogICAgICAgIDM1ICAzNiAgNzcgIDIyICAgICAgICAgICAgICAgICAgICAgIDIzICAzMiAgNTQgIDI0CiAgICAgIDMzICAwNyAgMDIgIDA0ICAyMSAgICAgICAgICAgICAgICAgIDU0ICAwNyAgMDcgIDA3ICA3NgogICAgMjAgIDA0ICAwNyAgMDcgIDAxICAyMCAgICAgICAgICAgICAgNTQgIDExICA4MSAgODEgIDA3ICA3NgogIDIwICA2NyAgNjcgIDIyICAwNyAgMDEgIDc4ICAgICAgICAgIDU0ICAwNyAgODEgIDA3ICA4MSAgMDkgIDc2CjIwICA2NyAgMDcgIDY3ICAyMiAgMjIgIDA3ICA0NCAgNTUgIDU0ICAwNyAgODEgIDA3ICAwNyAgNjEgIDA3ICAyMAogIDY3ICA1NyAgNTAgIDUwICAwNyAgMDcgIDE0ICAwMyAgMDIgIDE1ICA4MSAgOTkgIDkxICAwNyAgODEgIDA0CjY3ICAwNyAgNTAgICAgICA1MCAgODcgIDM5ICA0NSAgNDEgIDM0ICA4MSAgMDcgIDA3ICA4OSAgMDcgIDgxICA3OQogIDY3ICAwNyAgNTAgIDUwICAwNyAgMDcgIDA3ICAyNyAgMDcgIDI3ICA4MSAgMDcgIDA3ICA3OSAgODEgIDc4CjIwICA2NyAgNjcgIDA3ICAwNyAgMDcgIDA3ICA5OSAgMzMgIDQ2ICAwMiAgODEgIDA3ICAwNyAgODEgIDAxICAyMAogIDMzICAwNyAgMDcgIDAxICAwNSAgMDEgIDkyICAgICAgICAgIDIwICAwMiAgODEgIDA3ICA4MSAgMTUgIDMyCiAgICAyMiAgMDcgIDIwICAyMCAgMDcgIDIwICAgICAgICAgICAgICA2MyAgMDIgIDgwICA4MSAgMTUgIDMyCiAgICAgIDQ1ICAyMCAgMDEgIDIwICAzOSAgICAgICAgICAgICAgICAgIDIwICAxNSAgMDcgIDE1ICAzMgogICAgICAgIDIzICAyMCAgMjAgIDI5ICA0MyAgMjEgIDE4ICA0MSAgMjAgIDY2ICA2NiAgNDMgIDIxCiAgICAgIDkwICAgICAgICAgICAgICAgICAgOTkgIDQ3ICAwNyAgMjAKICAgIDUwICAgICAgICAgICAgICAgICAgICAgIDIwICAwMiAgNDgKICA3MCAgICAgICAgICAgICAgICAgICAgICAgICAgNTYgIDIwCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOTAKRU9TCgogICAgYXNzZXJ0X2VxdWFsIDE0MzIsIGZbaW5wdXRdCiAgZW5kCmVuZAo=