- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Program to check person can reach top-left or bottomright cell avoiding fire or not in Python
Suppose we have a 2D matrix with few different values like below −
0 for empty cell
1 for a person
2 for fire
3 for a wall
Now assume there is only one person and in each turn the fire expands in all four directions (up, down, left and right) but fire cannot expand through walls. We have to check whether the person can move to either the top-left corner or the bottom-right corner or the matrix. We have to keep in mind that in each turn, the person moves first, then the fire expands. If the person makes it to any of the target cells as the same time as the fire, then he is safe. So if person go to the cell and then the fire expands in the same turn to the same cell, the person still survives.
So, if the input is like
0 | 0 | 0 |
0 | 0 | 1 |
0 | 0 | 2 |
then the output will be True, as the person can go to the top left corner.
To solve this, we will follow these steps −
R := row count of A, C := column count of A
Define a function bfs() . This will take queue
dist := a map that contains key as node of queue and all values are 0
while queue is not empty, do
node := left item of queue, then delete left item
for each neighbor nei of node, do
if nei is not in dist, then
dist[nei] := dist[node] + 1
insert nei at the end of queue
return dist
From the main method do the following −
fire_que := a double ended queue
person_que := a double ended queue
for each row index r and row A, do
for each column index c and value v in row, do
if v is same as 1, then
insert pair (r, c) at the end of person_que
otherwise when v is same as 2, then
insert pair (r, c) at the end of fire_que
dist_fire := bfs(fire_que)
dist_person := bfs(person_que)
for each place in (0, 0), (R − 1, C − 1), do
if (dist_fire[place] if not exists then INF) >= (dist_person[place] if not exists then, 2 * INF), then
return True
return False
Let us see the following implementation to get better understanding −
Example
from collections import deque class Solution: def solve(self, A): INF = int(1e9) R, C = len(A), len(A[0]) def get_nei(r, c): for nr, nc in [[r − 1, c], [r, c − 1], [r + 1, c], [r, c + 1]]: if 0 <= nr < R and 0 <= nc < C and A[nr][nc] != 3: yield nr, nc def bfs(queue): dist = {node: 0 for node in queue} while queue: node = queue.popleft() for nei in get_nei(*node): if nei not in dist: dist[nei] = dist[node] + 1 queue.append(nei) return dist fire_que = deque() person_que = deque() for r, row in enumerate(A): for c, v in enumerate(row): if v == 1: person_que.append((r, c)) elif v == 2: fire_que.append((r, c)) dist_fire = bfs(fire_que) dist_person = bfs(person_que) for place in ((0, 0), (R− 1, C− 1)): if dist_fire.get(place, INF) >= dist_person.get(place, 2 * INF): return True return False ob = Solution() matrix = [ [0, 0, 0], [0, 0, 1], [0, 0, 2] ] print(ob.solve(matrix))
Input
[ [0, 0, 0], [0, 0, 1], [0, 0, 2] ]
Output
True