Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find a path a continuous path in a rectangular area without engaging a bomb in Python
Suppose we are given an array mat where the elements are of this form [p, q, r] where p and 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.
Problem Example
If the input is like mat =
| 0 | 1 | 2 |
| 3 | 2 | 1 |
| 2 | 1 | 1 |
with w = 4, then the output will be False.
Algorithm Steps
To solve this, we will follow these steps −
- Define a function
insec()to check if two bombs intersect. This will takep,qx1 := p[1], x2 := q[1]y1 := p[2], y2 := q[2]r1 := p[3], r2 := q[3]d := (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)dec := (r1 + r2) * (r1 + r2)- return
Trueifd <= dec, else returnFalse
- Sort the matrix based on the x coordinate values minus radius
temp := a new list- If
mat[0][0] - mat[0][2] > 0, then returnTrue - For each
p, q, rinmat, domin_wid := p - rmax_wid := p + r- If size of
tempis same as 0, then add list containing(p + r, p, q, r, p - r, p + r)at the end oftemp - Otherwise, find intersecting bombs and merge their width ranges
- If
min_wid <= 0andmax_wid >= w, then returnFalse
- Return
True
Example
Let us see the following implementation to get better understanding −
from bisect import bisect_left, insort
def solve(mat, w):
# Sort bombs by leftmost position (x - radius)
mat.sort(key=lambda i: i[0] - i[2])
temp = []
# If first bomb doesn't reach left edge, path is possible
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:
# Find position to insert current bomb
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]
# Check intersection with existing bombs
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 bombs block entire width, no path possible
if min_wid <= 0 and max_wid >= w:
return False
return True
def insec(p, q):
"""Check if two bombs intersect based on their positions and radii"""
x1, y1, x2, y2 = p[1], p[2], q[1], q[2]
r1, r2 = p[3], q[3]
# Calculate distance between bomb centers
d = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)
# Calculate sum of radii squared
dec = (r1 + r2) * (r1 + r2)
return d <= dec
# Test the function
bombs = [[0, 1, 2], [3, 2, 1], [2, 1, 1]]
width = 4
result = solve(bombs, width)
print(f"Can draw path: {result}")
Output
Can draw path: False
How It Works
The algorithm works by −
- Sorting bombs by their leftmost position to process them in order
-
Tracking intersections between bomb safety zones using the
insec()function - Merging ranges when bombs intersect to find blocked areas
- Checking coverage if any merged range covers the entire width from 0 to w
If at any point the merged bomb ranges cover the entire width of the rectangle, then no continuous path can be drawn without engaging a bomb.
Conclusion
This algorithm efficiently determines if a safe path exists through a minefield by sorting bombs and checking for overlapping danger zones. The solution returns False when bombs completely block the passage and True when a safe continuous path can be drawn.
