62 lines
1.6 KiB
Python
62 lines
1.6 KiB
Python
|
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
|