Find all rectangles filled with 0 in Python

PythonServer Side ProgrammingProgramming

Suppose we have a binary 2D matrix, now we have to find the beginning point and terminating point of all rectangles filled with 0s. We have to keep in mind that rectangles are separated and do not touch each other however they can touch the array boundary. A rectangle with only single element is also possible.

So, if the input is like −

1011101
1101111
1011001
1011001
1011011
1010000
1110001
1011101

then the output will be [[0, 1, 0, 1], [0, 5, 0, 5], [1, 2, 1, 2], [2, 3, 2, 4], [3, 1, 5, 1], [3, 4, 6, 5], [5, 3, 6, 5], [7, 1, 7, 1], [7, 5, 7, 5]]

To solve this, we will follow these steps −

  • Define a function find_rect() . This will take i,j,a,output,index
  • x := row count
  • y := col count
  • flag_col := 0
  • flag_row := 0
  • for m in range i to x, do
    • if a[m, j] is same as 1, then
      • flag_row := 1
      • break
    • if a[m, j] is same as 5, then
      • do nothing
    • for n in range j to y, do
      • if a[m, n] is same as 1, then
        • flag_col := 1
        • break
      • a[m, n] := 5
    • if flag_row is same as 1, then
      • insert m-1 at the end of output[index]
    • otherwise,
      • insert m at the end of output[index]
    • if flag_col is same as 1, then
      • insert n-1 at the end of output[index]
    • otherwise,
      • insert n at the end of output[index]
  • From the main method, do the following −
  • n := size of a
  • op := a new list
  • idx := -1
  • for i in range 0 to n, do
    • for j in range 0 to size of a[0], do
      • if a[i, j] is same as 0, then
        • insert [i,j] into op
        • idx := idx + 1
        • find_rect(i, j, a, op, idx)
  • display op

Example Code 

Let us see the following implementation to get better understanding −

 Live Demo

def find_rect(i,j,a,output,index):
   x = len(a)
   y = len(a[0])
   flag_col = 0
   flag_row = 0
   for m in range(i,x):
      if a[m][j] == 1:
         flag_row = 1
         break
      if a[m][j] == 5:
         pass
      for n in range(j, y):
         if a[m][n] == 1:
            flag_col = 1
            break
         a[m][n] = 5
   if flag_row == 1:
      output[index].append( m-1)
   else:
      output[index].append(m)
   if flag_col == 1:
      output[index].append(n-1)
   else:
      output[index].append(n)
def get_coord(a):
   n = len(a)
   op = []
   idx = -1
   for i in range(0,n):
      for j in range(0, len(a[0])):
         if a[i][j] == 0:
         op.append([i, j])
         idx = idx + 1
         find_rect(i, j, a, op, idx)
   print (op)
tests = [[1, 0, 1, 1, 1, 0, 1],
         [1, 1, 0, 1, 1, 1, 1],
         [1, 1, 1, 0, 0, 1, 1],
         [1, 0, 1, 1, 0, 0, 1],
         [1, 0, 1, 1, 0, 1, 1],
         [1, 0, 1, 0, 0, 0, 0],
         [1, 1, 1, 0, 0, 0, 1],
         [1, 0, 1, 1, 1, 0, 1]]
get_coord(tests)

Input

[[1, 0, 1, 1, 1, 0, 1],
[1, 1, 0, 1, 1, 1, 1],
[1, 1, 1, 0, 0, 1, 1],
[1, 0, 1, 1, 0, 0, 1],
[1, 0, 1, 1, 0, 1, 1],
[1, 0, 1, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 1],
[1, 0, 1, 1, 1, 0, 1]]

Output

[[0, 1, 0, 1], [0, 5, 0, 5], [1, 2, 1, 2], [2, 3, 2, 4], [3, 1, 5, 1], [3, 4, 6, 5], [5, 3, 6, 5], [7, 1, 7, 1], [7, 5, 7, 5]]
raja
Published on 23-Jul-2020 08:55:43
Advertisements