def max_sum(triangle_matrix):
    """Finds maximum sum of path from top of triangle down to bottom.

    Input: Matrix of triangle e.g.
      1
     3 5
    7 8 4
    becomes [[1], [3, 5], [7, 8, 4]]
    Uses memoization from the bottom layer up to work quickly
    Output: maximum value
    """
    max_depth = len(triangle_matrix) - 1

    # Set bottom row for memoization
    depth = max_depth
    result = {}
    for i, entry in enumerate(triangle_matrix[depth]):
        result[(i, max_depth - depth)] = entry
    depth -= 1

    # Set each row moving up the triangle based on
    # the results one low below
    while depth >= 0:
        for i, entry in enumerate(triangle_matrix[depth]):
            val_left = result[(i, max_depth - depth - 1)]
            val_right = result[(i + 1, max_depth - depth - 1)]
            result[(i, max_depth - depth)] = entry + max(val_left, val_right)
        depth -= 1

    return result[(0, max_depth - depth - 1)]