You are given a list of routers and their 2D location coordinates, a source router, a destination router, and a range value.
Each router, when it receives a message without collision, broadcasts the message to other routers which are within range.
Whenever a router broadcasts a message, it shuts down permanently and cannot broadcast again.
Write an implementation for a method which determines whether a message starting from a source router is reachable to a destination router without collision.
The distance between two routers is calculated using Euclidean distance.
Assume the time for a message to reach any router is proportional to the Euclidean distance between the sending router and the receiving router.
For deterministic testing, use the Euclidean distance itself as the message travel time.
Router Format
Each router is represented as a string in the format:
"routerId,x,y"
For example:
"A,0,0"
means router A is located at coordinate (0, 0).
Method Signature
boolean canReachDestination(List<String> routers, String sourceRouter, String destinationRouter, double range)
routers: list of routers, where each router is represented as "routerId,x,y"
sourceRouter: router from which the message starts at time 0
destinationRouter: router which should receive a non-collided message
range: maximum Euclidean distance within which one router can send a message to another router
- Returns
true if the destination router receives the message without collision, otherwise returns false
Behavior
A router can send a message to another router only if the Euclidean distance between them is less than or equal to range.
If either sourceRouter or destinationRouter does not exist in routers, return false.
If the source router is the same as the destination router and it exists in routers, return true.
The source router starts with the message at time 0, broadcasts immediately, and then shuts down.
If a router receives exactly one message at its earliest arrival time, it receives the message successfully.
A router that receives the message successfully broadcasts it immediately to all routers within range and then shuts down permanently.
If a router receives two or more messages at the same earliest arrival time, those messages collide and are discarded.
For comparing arrival times, two times are considered equal if their absolute difference is less than or equal to 0.1.
A router that receives collided messages does not broadcast.
Messages that arrive at a router after its earliest arrival time are ignored.
A router is considered reachable only if it receives exactly one non-collided message.
Constraints
1 ≤ routers.size() ≤ 10^4
- Each router string is in the format
"routerId,x,y"
x and y are integers
routerId is a non-empty string and does not contain a comma
- All router ids are unique
-10^6 ≤ x, y ≤ 10^6
0 ≤ range ≤ 10^9
sourceRouter and destinationRouter are non-empty strings
- Input parameters will never be
null
Examples
Example 1
canReachDestination(routers = ["A,0,0", "B,3,4", "C,4,3", "D,7,7"], sourceRouter = "A", destinationRouter = "D", range = 6.0)
Output:
false
Explanation:
Router A broadcasts at time 0.
Router A reaches router B at time 5.0.
Router A reaches router C at time 5.0.
Router B receives exactly one message at time 5.0, so it broadcasts immediately.
Router C receives exactly one message at time 5.0, so it broadcasts immediately.
Router B reaches router D at time 10.0.
Router C reaches router D at time 10.0.
Since router D receives two messages at the same earliest arrival time, the messages collide and router D is not considered reachable.
Example 2
canReachDestination(routers = ["A,0,0", "B,3,4", "C,6,0", "D,9,0"], sourceRouter = "A", destinationRouter = "D", range = 6.0)
Output:
true
Explanation:
Router A broadcasts at time 0.
Router A reaches router B at time 5.0.
Router A reaches router C at time 6.0.
Router B can reach router C, but that message would arrive at time 10.0, which is after router C's earliest arrival time, so it is ignored.
Router C broadcasts at time 6.0.
Router C reaches router D at time 9.0.
Router D receives exactly one message at its earliest arrival time, so it is reachable.
Example 3
canReachDestination(routers = ["A,0,0", "B,0,8", "C,0,17", "D,11,0"], sourceRouter = "A", destinationRouter = "D", range = 10.0)
Output:
false
Explanation:
Router A broadcasts at time 0.
Router A reaches router B at time 8.0.
Router A cannot directly reach router D because the distance from A to D is 11.0, which is greater than the range.
Router B receives exactly one message, so it broadcasts immediately.
Router B reaches router C at time 17.0.
Router B cannot reach router D because the distance from B to D is greater than the range.
Router C also cannot reach router D.
Therefore, router D never receives a non-collided message.
Example 4
canReachDestination(routers = ["A,0,0", "B,0,8", "C,0,17"], sourceRouter = "A", destinationRouter = "A", range = 10.0)
Output:
true
Explanation:
The source router is the same as the destination router, and router A exists in the input list.
Example 5
canReachDestination(routers = ["A,0,0", "B,3,4", "C,4,3", "D,7,7"], sourceRouter = "X", destinationRouter = "D", range = 6.0)
Output:
false
Explanation:
Router X does not exist in the input list, so the method returns false.