Skip to content

Instantly share code, notes, and snippets.

@syminical
Created July 20, 2020 07:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save syminical/9c41dbfaa0c610fa6bb840acd3d5f323 to your computer and use it in GitHub Desktop.
Save syminical/9c41dbfaa0c610fa6bb840acd3d5f323 to your computer and use it in GitHub Desktop.
This method calculates the shortest distance in a 2D matrix. The input matrix is a string, and the rows are separated by semi-colons.
# Copyright (C) 2020 Alexandru Manaila
# Python3
def calculateDistance(cityMap):
#helpers
def addSpot(x, y, v):
#spot is valid for a path, and spot has not been visted or overlaping path is shorter.
if mapMatrix[y][x] == '_' and (distanceMatrix[y][x] == -1 or distanceMatrix[y][x] > v):
#New spot has to be checked.
pathStack.append((x, y))
#Distance to new path updated.
distanceMatrix[y][x] = v
#environment
rows = cityMap.split(';')
mapMatrix = [[c for c in row] for row in rows]
nRows = len(mapMatrix)
nCols = len(mapMatrix[0])
distanceMatrix = [[-1 for i in range(nCols)] for j in range(nRows)];
officerX, officerY = -1, -1
targetX, targetY = -1, -1
#Find the coordinates of Officer and Target.
for i in range(nRows):
for j in range(nCols):
if mapMatrix[i][j] == 'O':
officerX, officerY = j, i
elif mapMatrix[i][j] == 'T':
targetX, targetY = j, i
pathStack = [(officerX, officerY)]
#Invalid input case, return value obtained from test case.
if officerX == -1 or officerY == -1 or targetX == -1 or targetY == -1:
return -2
#Fill in distance matrix. - There is a bug here, but I don't have enough time. sorry
distanceMatrix[officerY][officerX] = 0
while pathStack:
#Each iteration completes in a cell in the distance matrix.
#Determine new spot candidates counter-clockwise, and evaluate clockwise.
spot = pathStack.pop()
#up
x, y = spot[0], spot[1]-1
if y > -1:
addSpot(x, y, distanceMatrix[spot[1]][spot[0]] + 1)
#left
x, y = spot[0]-1, spot[1]
if x > -1:
addSpot(x, y, distanceMatrix[spot[1]][spot[0]] + 1)
#down
x, y = spot[0], spot[1]+1
if y < nRows:
addSpot(x, y, distanceMatrix[spot[1]][spot[0]] + 1)
#right
x, y = spot[0]+1, spot[1]
if x < nCols:
addSpot(x, y, distanceMatrix[spot[1]][spot[0]] + 1)
#Find shortest path to target.
#Path lengths end around T, so find smallest value from valid path spots.
ret = []
#up
x, y = targetX, targetY-1
#Coordinate is in bounds, and spot is not a wall.
if y > -1 and distanceMatrix[y][x] != -1:
ret.append(distanceMatrix[y][x])
#left
x, y = targetX-1, targetY
if x > -1 and distanceMatrix[y][x] != -1:
ret.append(distanceMatrix[y][x])
#down
x, y = targetX, targetY+1
if y < nRows and distanceMatrix[y][x] != -1:
ret.append(distanceMatrix[y][x])
#right
x, y = targetX+1, targetY
if x < nCols and distanceMatrix[y][x] != -1:
ret.append(distanceMatrix[y][x])
if ret:
smallest = ret[0];
for i in ret:
if i < smallest:
smallest = i
else:
#No path found, return value obtained from test case.
return -1
print('O: ', officerX, ', ', officerY)
print('T: ', targetX, ', ', targetY)
print()
for row in mapMatrix:
print(row)
print()
for row in distanceMatrix:
print(row)
print()
print('ret:', ret)
print()
return smallest + 1
print(calculateDistance('O__;_XT;___'))
print('------------------')
print(calculateDistance('OX_;XXT;___'))
print('------------------')
print(calculateDistance('X__;_XT;___'))
print('------------------')
print(calculateDistance('OXXX____;__XTXXX_;X_X_X___;X_____X_'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment