# Program to find out is a point is reachable from the current position through given points in Python

PythonServer Side ProgrammingProgramming

Suppose in a 2D space a pointer is located at a point p that has coordinates (px, py). Now the pointer has to move to another point q having coordinates (qx, qy). The pointer just cannot move freely, it can travel to q if there are some points located in between. We are given an array of points "paths" that contain various coordinate points. The pointer can move to a point if it is located at (x+1, y) or (x, y+1) or (x-1, y) or (x, y-1) from the current position of the pointer. The given points in the array 'paths' have to be processed serially in order, which means each point in the array has to be added up to the total path even if the move cannot be made. So, given the starting and destination points, we have to find out if the pointer can reach the destination from the given points. If it can, we print out the total number of points it traversed to get to the destination; and if it can't we print -1.

So, if the input is like px = 1, py = 1, qx = 2, qy = 3, paths = [[1, 2], [0, 1], [0, 2], [1, 3], [3, 3]], then the output will be 4.

So, if we process the points serially, we get −

Point (1, 2): Move is made, current pointer position (1, 2). Points traversed: 1.

Point (0, 1): No move is made, current pointer position (1, 2). Points traversed: 2.

Point (0, 2): No move is made, current pointer position (1, 2). Points traversed: 3.

Point (1, 3): Move is made, current pointer position (1, 3). Points traversed: 4.

The destination is located at (x+1, y) location from the current pointer position, so the total number of points traversed is 4.

To solve this, we will follow these steps −

• Define a function helper() . This will take k
• vertices := a new set containing pairs (px, py) and (qx, qy)
• for each x, y in paths upto position k, do
• add pair (x, y) to vertices
• trav:= a new deque containing pair (px, py)
• while trav is not empty, do
• pair (x, y) := pop the leftmost item from trav
• if (x, y) is same as (qx, qy), then
• return True
• for each kx, ky in ((x - 1, y),( x + 1, y), (x, y – 1), (x, y + 1)), do
• if pair (kx, ky) is present in vertices, then
• insert pair (kx, ky) at the end of trav
• delete pair (kx, ky) from vertices
• return False
• ll := -1
• ul := size of paths + 1
• while ll + 1 < ul, do
• k := ll + floor value of ((ul - ll) / 2)
• if helper(k) is True, then
• ul := k
• otherwise,
• ll := k
• return ul if ul <= size of paths, otherwise return -1

## Example

Let us see the following implementation to get better understanding −

from collections import deque
def solve(px, py, qx, qy, paths):
def helper(k):
vertices = {(px, py), (qx, qy)}
for x, y in paths[:k]:
trav = deque([(px, py)])
while trav:
x, y = trav.popleft()
if (x, y) == (qx, qy):
return True
for kx, ky in ((x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)):
if (kx, ky) in vertices:
trav.append((kx, ky))
vertices.remove((kx, ky))
return False
ll, ul = -1, len(paths) + 1
while ll + 1 < ul:
k = ll + (ul - ll) // 2
if helper(k):
ul = k
else:
ll = k
return ul if ul <= len(paths) else -1

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

## Input

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

## Output

4