""" By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23. 3 7 4 2 4 6 8 5 9 3 That is, 3 + 7 + 4 + 9 = 23 . Find the maximum total from top to bottom of the triangle below: 75 95 64 17 47 82 18 35 87 10 20 04 82 47 65 19 01 23 75 03 34 88 02 77 73 07 63 67 99 65 04 28 06 16 70 92 41 41 26 56 83 40 80 70 33 41 48 72 33 47 32 37 16 94 29 53 71 44 65 25 43 91 52 97 51 14 70 11 33 28 77 73 17 78 39 68 17 57 91 71 52 38 17 14 91 43 58 50 27 29 48 63 66 04 68 89 53 67 30 73 16 69 87 40 31 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23 """ TXT = """75 95 64 17 47 82 18 35 87 10 20 04 82 47 65 19 01 23 75 03 34 88 02 77 73 07 63 67 99 65 04 28 06 16 70 92 41 41 26 56 83 40 80 70 33 41 48 72 33 47 32 37 16 94 29 53 71 44 65 25 43 91 52 97 51 14 70 11 33 28 77 73 17 78 39 68 17 57 91 71 52 38 17 14 91 43 58 50 27 29 48 63 66 04 68 89 53 67 30 73 16 69 87 40 31 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23""" def triangle_best_choice(triangle: list[list[int]]) -> tuple[int, int]: if len(triangle) == 2: res = max(triangle[1][0], triangle[1][1]) index = triangle[1].index(res) return res, index else: one = max(triangle[1][0] + triangle[2][0], triangle[1][0] + triangle[2][1]) two = max(triangle[1][1] + triangle[2][1], triangle[1][1] + triangle[2][2]) if one >= two: return triangle[1][0], 0 else: return triangle[1][1], 1 def triangle_best_path(triangle: list[list[int]]) -> list[int]: max_len = len(triangle) if max_len == 1: return triangle[0] coln = 0 res = triangle[0] for i in range(max_len - 1): if i + 2 < max_len: keypart = [ triangle[i][coln : coln + 1], triangle[i + 1][coln : coln + 2], triangle[i + 2][coln : coln + 3], ] else: keypart = [triangle[i][coln : coln + 1], triangle[i + 1][coln : coln + 2]] tres, delta = triangle_best_choice(keypart) res.append(tres) coln += delta return res def main() -> None: data = TXT.split("\n") triangle = [list(map(int, row.split())) for row in data] res = triangle_best_path(triangle) print(f"{sum(res)} = {' + '.join(map(str, res))}") if __name__ == "__main__": main()