Project Euler Problem #82

Problem #82 is a more complex version of Problem #81. The question reads:

Project Euler Problem 82: Path sum: three ways
The minimal path sum in the 5 by 5 matrix below, by starting in any cell in the left column and finishing in any cell in the right column, and only moving up, down, and right, is indicated in red and bold; the sum is equal to 994.

131 673 234 103 018
201 096 342 965 150
630 803 746 422 111
537 699 497 121 956
805 732 524 037 331

Find the minimal path sum from the left column to the right column in matrix.txt (right click and "Save Link/Target As..."), a 31K text file containing an 80 by 80 matrix.

As mentioned above, this problem is very similar to Problem 81. The only difference is that in this case, the path can start anywhere on the left edge and it can move up. These changes do not require the solution to be significantly different, so my solution for this problem is similar to my solution for Problem 81. Here’s my solution:

Solution #1: Dynamic Approach

We simply go from left to right across the grid, finding the minimum path sum to each cell one column at a time. The first column can be found by simply storing the first column of the given grid. Each successive column can be calculated by iterating through the previous column and finding the minimum path sum from each cell in the previous column to each cell in the next column. By this method, the minimum path to each column can be generated dynamically. Here is an implementation of this approach in Python 2.7:

 '''
 Author: Walker Kroubalkian
 Dynamic Approach to Project Euler Problem #82
 '''
 
 import time
 
 f = open("PE82Grid.txt","r")
 
 if(f.mode == "r"):
     contents = f.readlines()
     realContents = []
     for x in contents:
         realContents.append(map(int,x.split(",")))
 else:
     raise ValueError("Cannot read from file")
 
 def projectEulerProblemEightyTwo(myGrid):
     newGrid = []
     rows = len(myGrid)
     cols = len(myGrid[0])
     for x in range(rows):
         newGrid.append([myGrid[x][0]])
     for y in range(1,cols):
         theColumn = []
         for x in range(rows):
             theColumn.append(myGrid[x][y])
         forwardPartials = [0]
         t = 0
         for x in theColumn:
             t+=x
             forwardPartials.append(t)
         backwardPartials = [t]
         for x in range(rows-1,-1,-1):
             t-=theColumn[x]
             backwardPartials.append(t)
         newColumn = []
         for z in range(rows):
             minFound = newGrid[z][y-1]+myGrid[z][y]
             for a in range(rows):
                 if(a<z):
                     total = myGrid[z][y] + forwardPartials[z]-forwardPartials[a] + newGrid[a][y-1]
                 elif(a>z):
                     total = myGrid[z][y] + forwardPartials[a+1] - forwardPartials[z+1] + newGrid[a][y-1]
                 else:
                     total = minFound
                 if(total<minFound):
                     minFound = total
             newColumn.append(minFound)
         for x in range(rows):
             newGrid[x].append(newColumn[x])
     minFound = newGrid[0][cols-1]
     for a in range(1,rows):
         v = newGrid[a][cols-1]
         if(v<minFound):
             minFound = v
     return minFound
 
 start = time.time()
 print projectEulerProblemEightyTwo(realContents)
 print ("--- %s seconds ---" % (time.time()-start))
 
 '''
 Prints

 260324
 --- 0.0795319080353 seconds ---
 
 for input of given grid.
 '''

And with that, we’re done. This solution still managed to run in under a tenth of a second, but it still took over an order of magnitude longer than the solution for Problem #81. I may come back to this problem to look for a more efficient implementation.

Thanks for reading! See you tomorrow.

Published by Walker Kroubalkian

My name is Walker Kroubalkian. I really enjoy math, computer science, and hiking.

Leave a comment

Design a site like this with WordPress.com
Get started