Program to find a path a continuous path in a rectangular area without engaging a bomb in Python

PythonServer Side ProgrammingProgramming

Suppose we are given an array mat where the elements are of this form [p, q, r] where p, q are geometric coordinates and r is a radius value. The items in the array are the locations of bombs in a rectangular area of a given width w. The rectangle is infinitely long and is bounded by x coordinates x = 0 to x = w. The r value in the bombs position signifies the safety radius of a bomb, meaning anything less than that radius of the bomb will engage it. So, what we have to do is to draw a continuous path that starts below every bomb and ends above every bomb without engaging any one of them. We will print True if we can draw this line, otherwise, we print False.

So, if the input is like mat =

012
321
211

, w = 4; then the output will be False.

To solve this, we will follow these steps −

  • Define a function insec() . This will take p, q
    • x1 := p[1], x2 := p[2]
    • y2 := q[1], y4 := q[2]
    • r1 := p[3], r2 := q[3]
    • d := (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)
    • dec :=(r1 + r2) *(r1 + r2)
    • return True if d <= dec, else return False
  • sort the matrix based on the x coordinate values
  • temp := a new list
  • if mat[0][0] - mat[0][2] > 0, then
    • return True
  • for each p, q, r in mat, do
    • min_wid := p - r
    • max_wid := p + r
    • if size of temp is same as 0, then
      • add list containing (p + r, p, q, r, p - r, p + r) at the end of temp
    • otherwise,
      • mx := maximum of (the position in temp where the list [p - r, -p, q, r, 0, 0] can be inserted maintaining the sorted order - 1) , 0
      • in_list := a new list containing elements (p + r, p, q, r, p - r, p + r)
      • for i in range mx to size of temp, do
        • if insec(temp[i], in_list) is True, then
          • max_wid = maximum of (max_wid, temp[i, -1])
        • min_wid = minimum of (min_wid, temp[i, -2])
      • second last element of in_list := min_wid
      • last_element of in_list := max_wid
      • insert in_list in temp maintaining the sorted order
    • if min_wid <= 0 and max_wid >= w, then
      • return False
  • return True

Example

Let us see the following implementation to get better understanding −

from bisect import bisect_left, insort
def solve(mat, w):
   mat.sort(key=lambda i: i[0] - i[2])
   temp = []
   if mat[0][0] - mat[0][2] > 0:
      return True
   for p, q, r in mat:
      min_wid, max_wid = p - r, p + r
      if len(temp) == 0:
         temp.append([p + r, p, q, r, p - r, p + r])
      else:
         mx = max(bisect_left(temp, [p - r, -p, q, r, 0, 0]) - 1, 0)

         in_list = [p + r, p, q, r, p - r, p + r]
         for i in range(mx, len(temp)):
             if insec(temp[i], in_list):
               max_wid = max(max_wid, temp[i][-1])
               min_wid = min(min_wid, temp[i][-2])
         in_list[-2] = min_wid
         in_list[-1] = max_wid
         insort(temp, in_list)
      if min_wid <= 0 and max_wid >= w:
         return False
   return True

def insec(p, q):
   x1, y1, x2, y2 = p[1], p[2], q[1], q[2]
   r1, r2 = p[3], q[3]
   d = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)
   dec = (r1 + r2) * (r1 + r2)
   return d <= dec

print(solve([[0, 1, 2],[3, 2, 1], [2, 1, 1]], 4))

Input

[[0, 1, 2],[3, 2, 1], [2, 1, 1]], 4

Output

False
raja
Published on 16-Oct-2021 11:20:03
Advertisements