Open In App

Minimizing Distance Between Two Walkers

Last Updated : 29 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given the starting and ending coordinates of path of two persons, the task is to find the minimum distance between the persons at any point of time. The first persons walks from (x1, y1) to (x2, y2) and the second person walks from (x3, y3) to (x4, y4). Both of these persons complete their walks in same amount of time.

Note: The answer should be correct up to 6 decimal places.

minimumDistance_1

Examples:

Input: x1 = 0, y1 = 0, x2 = 5, y2 = 0, x3 = 5, y3 = 5, x4 = 5, y4 = 0
Output: 0
Explanation: After they both have completed the walk, they are standing at same position so the minimum distance will be zero.

Input: x1 = 0, y1 = 0, x2 = 5, y2 = 5, x3 = 10, y3 = 10, x4 = 6, y4 = 6
Output: 1.4142135624
Explanation: The minimum distance between the two persons is when the first person is at (5, 5) and the second person is at (6, 6). Therefore, the minimum distance is 1.4142135624.

Minimizing Distance Between Two Walkers using Ternary Search:

If we observe carefully, we can see that the minimum distance between the two persons behaves as a Unimodal function. Since the distance is a Unimodal function, we can find the minimum distance between those 2 persons using Ternary Search. We can find 2 mid points ABmid1 and ABmid2 on Line AB and CDmid1 and CDmid2 on line CD. Since both the persons complete their walk in equal time interval, so when the first person reaches ABmid1, the second person would reach CDmid1 and when the first person reaches ABmid2, the second person would reach CDmid2. Now, calculate the distance between ABmid1 and CDmid1 as d1 and ABmid2 and CDmid2 as d2. Now according to the values of d1 and d2, we can have one of the three cases:

  • If d1 == d2, we can shift Point A to ABmid1, Point B to ABmid2, Point C to CDmid1 and Point D to CDmid2
  • Else if d1 < d2, we can shift Point B to ABmid2 and Point D to CDmid2
  • Else if d1 > d2, we can shift Point A to ABmid1 and Point C to CDmid1

Since the error limit is 1e-6 and in each iteration we are reducing our search space by a factor of at least 2/3. Therefore, 200 iterations are sufficient to get our answer.

Step-by-step approach:

  • Declare a class point to store x and y coordinates as its data members.
  • Find 2 mid points (ABmid1 and ABmid2) on line AB.
  • Find 2 mid points (CDmid1 and CDmid2) on line CD.
  • Store the distance between ABmid1 and CDmid1 as d1.
  • Store the distance between ABmid2 and CDmid2 as d2.
  • Reduce the search space according to the values of d1 and d2.
  • After 200 iterations, return the answer as distance between point A and point C.

Below is the implementation of the above approach:

C++




#include <bits/stdc++.h>
#define ll long long
using namespace std;
 
// Class to store x and y coordinates as its data members
class Point {
public:
    double x, y;
    // Inline Constructors
    Point()
        : x(0)
        , y(0){};
    Point(double X, double Y)
        : x{ X }
        , y{ Y } {};
};
 
// Method to get the distance between two points
double getDistance(Point& P1, Point& P2)
{
    double dx = P1.x - P2.x;
    double dy = P1.y - P2.y;
    return sqrt(dx * dx + dy * dy);
}
 
// Method to get the first midpoint between two points
Point getMid1(Point& P1, Point& P2)
{
    double xmid1 = P1.x + (P2.x - P1.x) / 3.0;
    double ymid1 = P1.y + (P2.y - P1.y) / 3.0;
    return Point(xmid1, ymid1);
}
 
// Method to get the second midpoint between two points
Point getMid2(Point& P1, Point& P2)
{
    double xmid2 = P2.x - (P2.x - P1.x) / 3.0;
    double ymid2 = P2.y - (P2.y - P1.y) / 3.0;
    return Point(xmid2, ymid2);
}
 
// Method to find the minimum distance between 2 persons
double solve(Point& A, Point& B, Point& C, Point& D)
{
    int cnt = 200;
    // Reduce the seach space for 200 iterations
    while (cnt--) {
        // mid1 for line AB
        Point ABmid1 = getMid1(A, B);
 
        // mid2 for line AB
        Point ABmid2 = getMid2(A, B);
 
        // mid1 for line CD
        Point CDmid1 = getMid1(C, D);
 
        // mid2 for line CD
        Point CDmid2 = getMid2(C, D);
 
        double d1 = getDistance(ABmid1, CDmid1);
        double d2 = getDistance(ABmid2, CDmid2);
 
        // Reduce the search space using midpoints
        if (d1 == d2) {
            A = ABmid1;
            B = ABmid2;
            C = CDmid1;
            D = CDmid2;
        }
        else if (d1 < d2) {
            B = ABmid2;
            D = CDmid2;
        }
        else {
            A = ABmid1;
            C = CDmid1;
        }
    }
    return getDistance(A, C);
}
 
int main()
{
    Point A(0, 0), B(5, 5), C(10, 10), D(6, 6);
    cout << fixed << setprecision(6) << solve(A, B, C, D)
         << "\n";
    return 0;
}


Java




// Java Implementation
import java.util.*;
 
// Class to store x and y coordinates as its data members
class Point {
    double x, y;
   
    // Constructors
    Point() {
        x = 0;
        y = 0;
    }
 
    Point(double X, double Y) {
        x = X;
        y = Y;
    }
}
 
public class Main {
 
    // Method to get the distance between two points
    static double getDistance(Point P1, Point P2) {
        double dx = P1.x - P2.x;
        double dy = P1.y - P2.y;
        return Math.sqrt(dx * dx + dy * dy);
    }
 
    // Method to get the first midpoint between two points
    static Point getMid1(Point P1, Point P2) {
        double xmid1 = P1.x + (P2.x - P1.x) / 3.0;
        double ymid1 = P1.y + (P2.y - P1.y) / 3.0;
        return new Point(xmid1, ymid1);
    }
 
    // Method to get the second midpoint between two points
    static Point getMid2(Point P1, Point P2) {
        double xmid2 = P2.x - (P2.x - P1.x) / 3.0;
        double ymid2 = P2.y - (P2.y - P1.y) / 3.0;
        return new Point(xmid2, ymid2);
    }
 
    // Method to find the minimum distance between 2 persons
    static double solve(Point A, Point B, Point C, Point D) {
        int cnt = 200;
        // Reduce the search space for 200 iterations
        while (cnt-- > 0) {
            // mid1 for line AB
            Point ABmid1 = getMid1(A, B);
 
            // mid2 for line AB
            Point ABmid2 = getMid2(A, B);
 
            // mid1 for line CD
            Point CDmid1 = getMid1(C, D);
 
            // mid2 for line CD
            Point CDmid2 = getMid2(C, D);
 
            double d1 = getDistance(ABmid1, CDmid1);
            double d2 = getDistance(ABmid2, CDmid2);
 
            // Reduce the search space using midpoints
            if (d1 == d2) {
                A = ABmid1;
                B = ABmid2;
                C = CDmid1;
                D = CDmid2;
            } else if (d1 < d2) {
                B = ABmid2;
                D = CDmid2;
            } else {
                A = ABmid1;
                C = CDmid1;
            }
        }
        return getDistance(A, C);
    }
 
    public static void main(String[] args) {
        Point A = new Point(0, 0);
        Point B = new Point(5, 5);
        Point C = new Point(10, 10);
        Point D = new Point(6, 6);
 
        System.out.printf("%.6f%n", solve(A, B, C, D));
    }
}


Python3




import math
 
# Class to store x and y coordinates as its data members
class Point:
    def __init__(self, X=0, Y=0):
        self.x = X
        self.y = Y
 
# Method to get the distance between two points
def get_distance(P1, P2):
    dx = P1.x - P2.x
    dy = P1.y - P2.y
    return math.sqrt(dx * dx + dy * dy)
 
# Method to get the first midpoint between two points
def get_mid1(P1, P2):
    xmid1 = P1.x + (P2.x - P1.x) / 3.0
    ymid1 = P1.y + (P2.y - P1.y) / 3.0
    return Point(xmid1, ymid1)
 
# Method to get the second midpoint between two points
def get_mid2(P1, P2):
    xmid2 = P2.x - (P2.x - P1.x) / 3.0
    ymid2 = P2.y - (P2.y - P1.y) / 3.0
    return Point(xmid2, ymid2)
 
# Method to find the minimum distance between 2 persons
def solve(A, B, C, D):
    cnt = 200
    # Reduce the search space for 200 iterations
    while cnt > 0:
        # mid1 for line AB
        ABmid1 = get_mid1(A, B)
 
        # mid2 for line AB
        ABmid2 = get_mid2(A, B)
 
        # mid1 for line CD
        CDmid1 = get_mid1(C, D)
 
        # mid2 for line CD
        CDmid2 = get_mid2(C, D)
 
        d1 = get_distance(ABmid1, CDmid1)
        d2 = get_distance(ABmid2, CDmid2)
 
        # Reduce the search space using midpoints
        if d1 == d2:
            A = ABmid1
            B = ABmid2
            C = CDmid1
            D = CDmid2
        elif d1 < d2:
            B = ABmid2
            D = CDmid2
        else:
            A = ABmid1
            C = CDmid1
 
        cnt -= 1
 
    return get_distance(A, C)
 
# Driver code
if __name__ == "__main__":
    A = Point(0, 0)
    B = Point(5, 5)
    C = Point(10, 10)
    D = Point(6, 6)
 
    # Function call
    print("{:.6f}".format(solve(A, B, C, D)))


C#




using System;
 
// Class to store x and y coordinates as its data members
class Point
{
    public double x, y;
 
    // Constructors
    public Point()
    {
        x = 0;
        y = 0;
    }
 
    public Point(double X, double Y)
    {
        x = X;
        y = Y;
    }
}
 
class Program
{
    // Method to get the distance between two points
    static double GetDistance(Point P1, Point P2)
    {
        double dx = P1.x - P2.x;
        double dy = P1.y - P2.y;
        return Math.Sqrt(dx * dx + dy * dy);
    }
 
    // Method to get the first midpoint between two points
    static Point GetMid1(Point P1, Point P2)
    {
        double xmid1 = P1.x + (P2.x - P1.x) / 3.0;
        double ymid1 = P1.y + (P2.y - P1.y) / 3.0;
        return new Point(xmid1, ymid1);
    }
 
    // Method to get the second midpoint between two points
    static Point GetMid2(Point P1, Point P2)
    {
        double xmid2 = P2.x - (P2.x - P1.x) / 3.0;
        double ymid2 = P2.y - (P2.y - P1.y) / 3.0;
        return new Point(xmid2, ymid2);
    }
 
    // Method to find the minimum distance between 2 persons
    static double Solve(Point A, Point B, Point C, Point D)
    {
        int cnt = 200;
        // Reduce the search space for 200 iterations
        while (cnt-- > 0)
        {
            // mid1 for line AB
            Point ABmid1 = GetMid1(A, B);
 
            // mid2 for line AB
            Point ABmid2 = GetMid2(A, B);
 
            // mid1 for line CD
            Point CDmid1 = GetMid1(C, D);
 
            // mid2 for line CD
            Point CDmid2 = GetMid2(C, D);
 
            double d1 = GetDistance(ABmid1, CDmid1);
            double d2 = GetDistance(ABmid2, CDmid2);
 
            // Reduce the search space using midpoints
            if (d1 == d2)
            {
                A = ABmid1;
                B = ABmid2;
                C = CDmid1;
                D = CDmid2;
            }
            else if (d1 < d2)
            {
                B = ABmid2;
                D = CDmid2;
            }
            else
            {
                A = ABmid1;
                C = CDmid1;
            }
        }
        return GetDistance(A, C);
    }
 
    static void Main()
    {
        Point A = new Point(0, 0);
        Point B = new Point(5, 5);
        Point C = new Point(10, 10);
        Point D = new Point(6, 6);
 
        Console.WriteLine($"{Solve(A, B, C, D):F6}");
    }
}


Javascript




// javaScript code for the above approach
 
// Class to represent Point with x
// and y coordinates
class Point {
    constructor(X = 0, Y = 0) {
        this.x = X;
        this.y = Y;
    }
}
 
// Method to calculate distance
// between two points
function getDistance(P1, P2) {
    const dx = P1.x - P2.x;
    const dy = P1.y - P2.y;
    return Math.sqrt(dx * dx + dy * dy);
}
 
// Method to find the first midpoint
// between two points
function getMid1(P1, P2) {
    const xmid1 = P1.x + (P2.x - P1.x) / 3.0;
    const ymid1 = P1.y + (P2.y - P1.y) / 3.0;
    return new Point(xmid1, ymid1);
}
 
// Method to find the second midpoint
// between two points
function getMid2(P1, P2) {
    const xmid2 = P2.x - (P2.x - P1.x) / 3.0;
    const ymid2 = P2.y - (P2.y - P1.y) / 3.0;
    return new Point(xmid2, ymid2);
}
 
// Method to find the minimum distance
// between two persons
function solve(A, B, C, D) {
    let cnt = 200;
 
    while (cnt--) {
        // mid1 for line AB
        const ABmid1 = getMid1(A, B);
         
        // mid2 for line AB
        const ABmid2 = getMid2(A, B);
         
        // mid1 for line CD
        const CDmid1 = getMid1(C, D);
         
        // mid2 for line CD
        const CDmid2 = getMid2(C, D);
 
        const d1 = getDistance(ABmid1, CDmid1);
        const d2 = getDistance(ABmid2, CDmid2);
 
        if (d1 === d2) {
            A = ABmid1;
            B = ABmid2;
            C = CDmid1;
            D = CDmid2;
        }
        else if (d1 < d2) {
            B = ABmid2;
            D = CDmid2;
        }
        else {
            A = ABmid1;
            C = CDmid1;
        }
    }
    return getDistance(A, C).toFixed(6);
}
 
// Driver code
 
const A = new Point(0, 0);
const B = new Point(5, 5);
const C = new Point(10, 10);
const D = new Point(6, 6);
 
// Call solve function and display
// the result with precision
console.log(solve(A, B, C, D));


Output

1.414214








Time Complexity: O(log3( max(distance(A, B), distance(C, D)) )), where distance(A, B) is the distance between Point A and Point B and distance(C, D) is the distance between Point C and Point D.
Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads