Solve problem 150 by using prefix sum array. Nice.
This commit is contained in:
61
python/e150.py
Normal file
61
python/e150.py
Normal file
@@ -0,0 +1,61 @@
|
||||
def generate_triangle():
|
||||
t = 0
|
||||
ts = [[]]
|
||||
i_in_row, max_in_row = 0, 1
|
||||
for _ in range(1, 500_500 + 1):
|
||||
t = (615_949 * t + 797_807) % 2**20
|
||||
s = t - 2**19
|
||||
ts[-1].append(s)
|
||||
i_in_row += 1
|
||||
if i_in_row == max_in_row:
|
||||
i_in_row = 0
|
||||
max_in_row += 1
|
||||
ts.append([])
|
||||
ts.pop() # remove empty list
|
||||
return ts
|
||||
|
||||
|
||||
def array_to_prefix_sum_array(xs):
|
||||
ys = []
|
||||
current_sum = 0
|
||||
for x in xs:
|
||||
current_sum += x
|
||||
ys.append(current_sum)
|
||||
return ys
|
||||
|
||||
|
||||
def range_sum(prefix_sum, i, j):
|
||||
if i == 0:
|
||||
return prefix_sum[j]
|
||||
else:
|
||||
return prefix_sum[j] - prefix_sum[i - 1]
|
||||
|
||||
|
||||
def find_min_triangle(row_i, col_i, sum_triangle):
|
||||
current_sum, min_sum = 0, float("inf")
|
||||
left_i, right_i = col_i, col_i
|
||||
while row_i < len(sum_triangle):
|
||||
current_sum += range_sum(sum_triangle[row_i], left_i, right_i)
|
||||
row_i += 1
|
||||
right_i += 1
|
||||
min_sum = min(current_sum, min_sum)
|
||||
return min_sum
|
||||
|
||||
|
||||
def euler_150():
|
||||
triangle = generate_triangle()
|
||||
# triangle = [[15], [-14, -7], [20, -13, -5], [-3, 8, 23, -26], [1, -4 , -5, -18, 5], [-16, 31, 2, 9, 28, 3]]
|
||||
sum_triangle = [array_to_prefix_sum_array(xs) for xs in triangle]
|
||||
|
||||
min_triangle = float("inf")
|
||||
for row_i in range(len(triangle)):
|
||||
for col_i in range(len(triangle[row_i])):
|
||||
potential_min = find_min_triangle(row_i, col_i, sum_triangle)
|
||||
min_triangle = min(min_triangle, potential_min)
|
||||
return min_triangle
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
solution = euler_150()
|
||||
print("e150.py: " + str(solution))
|
||||
assert solution == -271248680
|
||||
Reference in New Issue
Block a user