Skip to content

Instantly share code, notes, and snippets.

@OzuYatamutsu
Last active July 31, 2018 02:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OzuYatamutsu/bcf6ddac0d15059581023a3c40b71df9 to your computer and use it in GitHub Desktop.
Save OzuYatamutsu/bcf6ddac0d15059581023a3c40b71df9 to your computer and use it in GitHub Desktop.
from collections import namedtuple
def find_max_area(heights: list, debug=False) -> int:
Point = namedtuple('Point', ['x', 'y'])
distance = lambda p2, p1: p2.x - p1.x if p2.x >= p1.x else p1.x - p2.x
move_point = lambda point, increment: Point(point.x + increment, heights[point.x + increment])
# Calculate area based on distance between lowest heights.
calc_max_area = lambda p2, p1: min(p2.y, p1.y) * distance(p2, p1)
# Initialize two pointers on either ends of the height list.
left_point, right_point = Point(0, heights[0]), Point(len(heights) - 1, heights[-1])
max_area = calc_max_area(left_point, right_point)
# ...and move 'em towards each other!
while left_point.x != right_point.x:
max_area = max(max_area, calc_max_area(left_point, right_point))
print(
"Current positions: "
f"Left point@({left_point.x}, {left_point.y}), "
f"Right point@({right_point.x}, {right_point.y}) "
f"(Max area is {max_area}.)\n" if debug else "", end=''
)
# If one side's height is lower than the other, that height may
# have room to improve. Move it towards the greater one.
if left_point.y < right_point.y:
left_point = move_point(left_point, 1)
else:
right_point = move_point(right_point, -1)
return max_area
@OzuYatamutsu
Copy link
Author

In [13]: find_max_area([1,1,3,2,1,1,3,1,20,20], debug=True)
Current positions: Left point@(0, 1), Right point@(9, 20) (Max area is 9.)
Current positions: Left point@(1, 1), Right point@(9, 20) (Max area is 9.)
Current positions: Left point@(2, 3), Right point@(9, 20) (Max area is 21.)
Current positions: Left point@(3, 2), Right point@(9, 20) (Max area is 21.)
Current positions: Left point@(4, 1), Right point@(9, 20) (Max area is 21.)
Current positions: Left point@(5, 1), Right point@(9, 20) (Max area is 21.)
Current positions: Left point@(6, 3), Right point@(9, 20) (Max area is 21.)
Current positions: Left point@(7, 1), Right point@(9, 20) (Max area is 21.)
Current positions: Left point@(8, 20), Right point@(9, 20) (Max area is 21.)
Out[13]: 21

In [14]: find_max_area([1,3,5,3,15])
Out[14]: 10

In [15]: find_max_area([1,1,5,1,1,1,1])
Out[15]: 6

In [16]: find_max_area([1,15,8,16,17,2])
Out[16]: 45

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment