136 lines
3.5 KiB
Python
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")))
|