from collections import namedtuple

def solution(A):

if len(A) < 3:

return 0

# The blocks in the stack is in strictly height descending order.

# For the first block in the stack, its max_depth is maximum water

# depth of its (exclusive) left area.

# The other blocks' max_depth is the maximum water depth between its

# previous block in the stack and itself, both exclusive.

Block = namedtuple("Block", ["height", "max_depth"])

stack = [Block(A[0],0)]

for height in A[1:]:

if height == stack[-1].height:

# These two adjacent blocks have the same height. They act

# totally the same in building any water container.

continue

elif height < stack[-1].height:

stack.append(Block(height, 0))

else:

max_depth = 0

# Let the current iterating block be C, the previous two

# blocks in the stack be A and B. And their positions are

# demoed as:

# C

# A C

# A ... B ... C

# while the blocks between A and B are omitted. So do the

# blocks between B and C.

#

# The additional_depth consider the blocks A, B, and C only,

# and igonres all the omitted blocks, such as:

# C

# A C

# A B C (no block is between A and B, or B and C)

#

# HOWEVER, the additional_depth is not always the maximum

# water depth between A and C, because there may be some

# water between A and B, or B and C, as exists in the omitted

# blocks. We need to adjust the additional_depth to get the

# maximum water depth between A and C, both exclusive.

while len(stack) > 1 and height > stack[-1].height:

additional_depth = min(stack[-2].height, height) - \

stack[-1].height

max_depth = max(max_depth, stack[-1].max_depth) + \

additional_depth

stack.pop()

# Combine leftward same-or-less-height blocks. These dropped

# blocks are never going to be part of the remaining water

# container.

while len(stack) > 0 and height >= stack[-1].height:

max_depth = max(max_depth, stack[-1].max_depth)

stack.pop()

stack.append(Block(height, max_depth))

overall_max_depth = 0

for block in stack:

if block.max_depth > overall_max_depth:

overall_max_depth = block.max_depth

return overall_max_depth