Project Euler Project 67 – Python

Question:

I am doing the Project Euler #67 in Python. My program, which worked for Project 18, does not work for Project 67.
Code (excludes the opening of the file and the processing of information):

for i in range(len(temp)):
    list1 = temp[i]
    try:
        list2 = temp[i+1]
        trynum1 = list1[lastinput] + max(list2[lastinput],list2[lastinput+1])
        try:
            trynum2 = list1[lastinput+1] + max(list2[lastinput+1],list2[lastinput+2])
            if trynum1 > trynum2:
                outputlist.append(list1[lastinput])
            else:
                outputlist.append(list1[lastinput+1])
                lastinput += 1
        except IndexError:
            outputlist.append(list1[0])
    except IndexError:
        if list1[lastinput] > list1[lastinput+1]:
            outputlist.append(list1[lastinput])
        else:
            outputlist.append(list1[lastinput+1])

Variables:

temp is the triangle of integers

outputlist is a list which stores the numbers chosen by the program

I know the answer is 7273, but my program finds 6542. I cannot find an error which causes the situation. Please may you help me on it.

Logic

My approach to this program is to find one number (list1[lastinput]) and add it up with the larger number of the two below it (trynum1), compare with the number to the right of the first number (list1[lastinput+1]), adding the larger number of two below it (trynum2). I append the larger one to the output list.

Asked By: rcw

||

Answers:

This approach is logically flawed. When you’re in row 1, you don’t have enough information to know whether moving right or left will lead you to the largest sum, not with only a 2-row lookahead. You would need to look all the way to the bottom to ensure getting the best path.

As others have suggested, start at the bottom and work up. Remember, you don’t need the entire path, just the sum. At each node, add the amount of the better of the two available paths (that’s the score you get in taking that node to the bottom). When you get back to the top, temp[0][0], that number should be your final answer.

Answered By: Prune

I thought day and night about problem 18 and I solved it, the same way I solved this one.
P.S. 100_triangle.txt is without 1st string ’59’.

# Maximum path sum II
import time
def e67():
    start = time.time()
    f=open("100_triangle.txt")
    summ=[59]
    for s in f:
        slst=s.split()
        lst=[int(item) for item in slst]
        for i in range(len(lst)):
            if i==0:
                lst[i]+=summ[i]
            elif i==len(lst)-1:
                lst[i]+=summ[i-1]
            elif (lst[i]+summ[i-1])>(lst[i]+summ[i]):
                lst[i]+=summ[i-1]
            else:
                lst[i]+=summ[i]
        summ=lst
    end = time.time() - start
    print("Runtime =", end)
    f.close()
    return max(summ)
print(e67()) #7273
Answered By: Mike Zubko

Though starting from the bottom is more efficient, I wanted to see if I could implement Dijkstra’s algorithm on this one; it works well and only takes a few seconds (didn’t time it precisely):

from math import inf

f = open("p067_triangle.txt", "r")
tpyramid = f.read().splitlines()
f.close()

n = len(tpyramid)

pyramid = [[100 - int(tpyramid[i].split()[j]) for j in range(i+1)] for i in range(n)]

paths = [[inf for j in range(i+1)] for i in range(n)]
paths[0][0] = pyramid[0][0]

def mini_index(pyr):
    m = inf
    for i in range(n):
        mr = min([i for i in pyr[i] if i >= 0]+[inf])
        if mr < m:
            m, a, b = mr, i, pyr[i].index(mr)
    return m, a, b

counter = 0

omega = inf

while counter < n*(n+1)/2:
    min_weight, i, j = mini_index(paths)
    if i != n-1:
        paths[i+1][j] = min( paths[i+1][j], min_weight + pyramid[i+1][j])
        paths[i+1][j+1] = min( paths[i+1][j+1], min_weight + pyramid[i+1][j+1])
    else:
        omega = min(omega, min_weight)
    paths[i][j] = -1
    counter += 1
    
print(100*n - omega)
Answered By: Swifty

Here is my solution. Indeed you have to take the bottom – up approach.
Result confirmed with PE. Thanks!

def get_triangle(listLink):
    triangle = [[int(number) for number in row.split()] for row in open(listLink)]
    return triangle

listOfLists = get_triangle('D:\Development\triangle.txt')

for i in range(len(listOfLists) - 2, -1, -1):
    for j in range(len(listOfLists[i])):
        listOfLists[i][j] += max(listOfLists[i+1][j], listOfLists[i+1][j+1])

print(listOfLists[0][0])
Answered By: Sigmatest
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.