project-euler/083_path_sum.py

136 lines
3.5 KiB
Python

#!/usr/bin/env python3
def deadeasy(matrix):
mx = len(matrix)
my = len(matrix[0])
change = True
cache = [[9999999 for y in range(my+2)] for x in range(mx+2)]
cache[1][1] = matrix[0][0]
while change:
change = False
for x in range(1, mx+1):
for y in range(1, my+1):
new_val = matrix[x-1][y-1] + min(cache[x+1][y], cache[x][y+1], cache[x-1][y], cache[x][y-1])
if new_val < cache[x][y]:
cache[x][y] = new_val
change = True
return cache[mx][my]
class Matrix:
def __init__(self, matrix):
self.x = self.y = 0
self.mx = len(matrix) - 1
self.my = len(matrix[0]) - 1
self.org = matrix
self.overlay = [[None for y in x] for x in matrix]
self.overlay[0][0] = self.org[0][0]
self.change = [[0 for y in x] for x in matrix]
def add(self, xshft, yshft):
x = self.x
y = self.y
xn = x + xshft
yn = y + yshft
chng_id = xshft + 2*yshft
#if chng_id == -self.change[x][y]:
#return False
new_val = self.overlay[x][y] + self.org[xn][yn]
if new_val < self.overlay[xn][yn] or self.overlay[xn][yn] == None:
self.overlay[xn][yn] = new_val
self.change[xn][yn] = chng_id
return True
return False
def right(self):
return self.add(1, 0)
def left(self):
return self.add(-1, 0)
def up(self):
return self.add(0, -1)
def down(self):
return self.add(0, 1)
def up(matrix):
matrix.y = matrix.my
while matrix.y > 0:
matrix.up()
matrix.y -= 1
def down(matrix):
matrix.y = 0
while matrix.y < matrix.my:
matrix.down()
matrix.y += 1
def right(matrix):
matrix.y = 0
while matrix.y <= matrix.my:
matrix.right()
matrix.y += 1
matrix.x += 1
def alter_right(matrix):
matrix.x = 0
while matrix.x < matrix.mx:
matrix.y = 0
while matrix.y <= matrix.my:
matrix.right()
matrix.y += 1
up(matrix)
down(matrix)
matrix.x += 1
def alter_left(matrix):
matrix.x = matrix.mx
while matrix.x > 0:
matrix.y = 0
while matrix.y <= matrix.my:
matrix.left()
matrix.y += 1
up(matrix)
down(matrix)
matrix.x -= 1
def left(matrix):
cont = True
matrix.x += 1
while cont and matrix.x > 1:
matrix.x -= 1
up(matrix)
down(matrix)
matrix.y = 0
cont = False
while matrix.y <= matrix.my:
cont = cont or matrix.left()
matrix.y += 1
def get_matrix(path):
with open(path) as f:
matrix = [map(int, row.split(",")) for row in f.read().split("\n")[:-1]]
return list(zip(*matrix))
def alter_main(matrix):
down(matrix)
prevm = False
while prevm != matrix.overlay[matrix.mx][matrix.my]:
prevm = matrix.overlay[matrix.mx][matrix.my]
alter_right(matrix)
alter_left(matrix)
return matrix.overlay[matrix.mx][matrix.my]
def main(matrix):
down(matrix)
while matrix.x < matrix.mx:
right(matrix)
left(matrix)
return matrix.overlay[matrix.mx][matrix.my]
if __name__ == "__main__":
matrix = [[131, 201, 630, 537, 805],
[673, 96, 803, 699, 732],
[234, 342, 746, 497, 524],
[103, 965, 422, 121, 37 ],
[18, 150, 111, 956, 331]
]
print(deadeasy(get_matrix("data/083_matrix.txt")))