The Scenario
You are given a matrix of size m x n (width x height) with m*n spots where there are a few obstacles. Spots with obstacles are marked as 1, and those without are marked as 0. You can move vertically or horizontally, but can visit each spot only once. The goal is to cover as much area/spots as possible, avoiding obstacles.
Input
A 2D Matrix consisting of 0s and 1s and the coordinates of starting point.
Example Matrix:
0 1 0
0 0 0
1 0 0
Starting Point (0,0). The coordinates are nothing but array indices.
Output
Output should be a line containing comma separated moves. A move is a space separated direction (n,s,e,w) and number of units of movement in the direction (range 1-1000).
Example output for the above matrix would be,
s 1,e 1,s 1,e 1,n 2
(0,0) --> (1,0) --> (1,1) --> (2,1) --> (2,2) --> (1,2) --> (0,2)
which is the longest path, visiting each coordinate only once and avoiding those coordinates with obstacles.
My algorithm
for every vertex/coordinate, recursively choose the neighbor which yields the longest path
Code
def getDirections(p1, p2):
return {(1,0):"n", (-1,0):"s", (0,1):"w", (0,-1):"e"}[(p1[0]-p2[0], p1[1]-p2[1])]
def findPath(start, mat):
m, paths = getMax(mat, getNeighbours(mat), start, list())
print(paths)
if len(paths) == 1:
return ""
directions = ""
prev = getDirections(paths[0], paths[1])
current = ""
ctr = 1
for i in range(1, len(paths)-1):
current = getDirections(paths[i], paths[i+1])
if current == prev:
ctr += 1
else:
directions, prev, ctr = directions + prev + " " + str(ctr) + ",", current, 1
return directions + current+ " " +str(ctr)
#Neighbor is (-1,-1) if indices are out of range. For top and bottom rows for example.
def getNeighbours(mat):
neighbours = dict()
for i in range(len(mat)):
for j in range(len(mat[i])):
n = (i-1, j) if i-1 >= 0 else (-1, -1)
s = (i+1, j) if i+1 < len(mat) else (-1, -1)
w = (i, j-1) if j-1 >= 0 else (-1, -1)
e = (i, j+1) if j+1 < len(mat[i]) else (-1, -1)
neighbours[(i,j)] = {'n':n, 's':s, 'w':w, 'e':e}
return neighbours
def getMax(mat, neighbours, coordinates, visited):
if coordinates == (-1,-1):
return -1, []
elif mat[coordinates[0]][coordinates[1]] == 1:
return -1, []
elif coordinates in visited:
return -1, []
else:
visited.append(coordinates)
n, nlist = getMax(mat, neighbours, neighbours[coordinates]['n'], visited[:])
s, slist = getMax(mat, neighbours, neighbours[coordinates]['s'], visited[:])
w, wlist = getMax(mat, neighbours, neighbours[coordinates]['w'], visited[:])
e, elist = getMax(mat, neighbours, neighbours[coordinates]['e'], visited[:])
if max(n,s,w,e) == -1:
return 0, visited
if max(n,s,w,e) == n:
visited = nlist
elif max(n,s,w,e) == s:
visited = slist
elif max(n,s,w,e) == w:
visited = wlist
elif max(n,s,w,e) == e:
visited = elist
return 1+max(n,s,w,e), visited
(0,0) --> (1,0)
, etc) in (Y,X) form? Seems that way (since going south would increment Y not X). Also, is there anything specific you want reviewed about your code? (i.e. OO, structure, naming, etc) \$\endgroup\$