Find Shortest distance from a guard in a Bankin Python


Suppose we have a matrix that is filled with three letters 'O', 'G', and 'W' where 'O' is representing open space, 'G' is representing guards and 'W' is representing walls in a bank, we have to replace all of the O's in the matrix with respect of their shortest distance from one guard, we cannot go through any walls. In the output matrix guards are replaced with 0 and walls are replaced by -1.

So, if the input is like

OOOOG
OOOWO
OWOOO
GWWWO
OOOOG

then the output will be

33210
233-11
1-1432
0-1-1-11
12210

To solve this, we will follow these steps −

  • M := 5

  • N := 5

  • dir_row := [-1, 0, 1, 0]

  • dir_col := [0, 1, 0, -1]

  • Define a function is_ok() . This will take i, j

  • if (i in range 0 and M) or (j in range 0 and j N), then

    • return False

  • return True

  • Define a function isSafe() . This will take i, j,matrix, result

  • if matrix[i, j] is not 'O' or result[i, j] is not -1, then

    • return False

  • return True

  • Define a function calculate_dist() .This will take matrix

  • result := make a matrix of order M x N and fill with -1

  • Define a double ended queue q

  • for i in range 0 to M, do

    • for j in range 0 to N, do

      • result[i, j] := -1

      • if matrix[i, j] is same as 'G', then

        • pos := [i, j, 0]

        • insert pos at the left of q

        • result[i, j] := 0

  • while size of q > 0 is non-zero, do

    • curr := delete last element from q

    • x, y, dist := curr[0], curr[1], curr[2]

    • for i in range 0 to 3, do

      • if is_ok(x + dir_row[i], y + dir_col[i]) is non-zero and isSafe(x + dir_row[i], y + dir_col[i], matrix, result) is non-zero, then

        • result[x + dir_row[i], y + dir_col[i]] := dist + 1

        • pos := [x + dir_row[i], y + dir_col[i], dist + 1]

        • insert pos at the left of q

  • for i in range 0 to M, do

    • for j in range 0 to N, do

      • display result[i, j]

    • go to next line

Example 

Let us see the following implementation to get better understanding −

from collections import deque as queue
M = 5
N = 5
dir_row = [-1, 0, 1, 0]
dir_col = [0, 1, 0, -1]
def is_ok(i, j):
   if ((i < 0 or i > M - 1) or (j < 0 or j > N - 1)):
      return False
   return True
def isSafe(i, j,matrix, result):
   if (matrix[i][j] != 'O' or result[i][j] != -1):
      return False
   return True
def calculate_dist(matrix):
   result = [[ -1 for i in range(N)]for i in range(M)]
   q = queue()
   for i in range(M):
      for j in range(N):
         result[i][j] = -1
         if (matrix[i][j] == 'G'):
            pos = [i, j, 0]
            q.appendleft(pos)
            result[i][j] = 0
   while (len(q) > 0):
      curr = q.pop()
      x, y, dist = curr[0], curr[1], curr[2]
   for i in range(4):
      if is_ok(x + dir_row[i], y + dir_col[i]) and isSafe(x + dir_row[i], y + dir_col[i], matrix, result) : result[x + dir_row[i]][y + dir_col[i]] = dist + 1
      pos = [x + dir_row[i], y + dir_col[i], dist + 1]
      q.appendleft(pos)
   for i in range(M):
      for j in range(N):
         if result[i][j] > 0:
            print(result[i][j], end=" ")
         else:
            print(result[i][j],end=" ")
      print()

matrix = [['O', 'O', 'O', 'O', 'G'],
   ['O', 'O', 'O', 'W', 'O'],
   ['O', 'W', 'O', 'O', 'O'],
   ['G', 'W', 'W', 'W', 'O'],
   ['O', 'O', 'O', 'O', 'G']]

calculate_dist(matrix)

Input

[['O', 'O', 'O', 'O', 'G'],
['O', 'O', 'O', 'W', 'O'],
['O', 'W', 'O', 'O', 'O'],
['G', 'W', 'W', 'W', 'O'],
['O', 'O', 'O', 'O', 'G']]

Output

3 3 2 1 0
2 3 3 -1 1
1 -1 4 3 2
0 -1 -1 -1 1
1 2 2 1 0

Updated on: 19-Aug-2020

85 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements