determine how many points one can travel given obstacles - algorithm

Suppose we have a field with coordinates, and the robot start from (0, 0), and can move up, down, left or right, but not diagonally.
For any given position (x, y), the robot can move to (x-1, y), (x+1, y), (x, y-1), (x, y+1), but not (x-1, y-1), (x+1, y+1), (x-1, y+1), (x+1, y-1).
In addition, there are obstacles placed in a way that any location whose coordinates' digits add up to 21 or more, e.g. (45, -94) is an obstacle point because 4 + 5 + 9 + 4 = 22 >= 21, but (-112, 223) is not because 1 + 1 + 2 + 2 + 2 + 3 = 11 < 21.
The robot cannot step into an obstacle or through it. It must move around it.
To determine the number of locations the robot can make, the first thought would be an exhaustive search with a breadth-first search.
- Is it the only way?
- Is there a faster way to do it?
- How can the knowledge of where obstacles are be used to solve it?

A point is an obstacle if either x or y = +/- 399, so there is a complete rectangle of obstacle points from (-399,-399) to (399,399).
Since you can't reach anything outside that rectangle, there are fewer than 640000 reachable points, and a simple BFS is probably a reasonable solution.

Related

Maximum bounty from two paths through a rectangular grid

I am trying to solve problem similar to this problem at GeeksforGeeks, yet different:
Given a rectangular 2-d grid with some coin value present in each cell, the task is to start from the top-left and bottom-right corner going right or down, and from bottom-right to top-left going left or up, maximizing the combined amount of coin picked. Coin in each cell can be picked only once.
The solution in the link is to start both traversal simultaneously but that's not going to work here.
How should I solve this? The brute force way of doing this would be enumerating all paths and picking two paths that maximizes the sum of coins picked but that's not going to work for large input.
We can solve this problem by making three observations:
First, rather than starting at two different points, we can reverse the direction of the second person, so the problem become two people start at the top left corner and move toward bottom right corner simultaneously.
Second, if we make an assumption that, two persons will make their move at the same speed, the state of these two can be represented by only three parameters: x1, x2 and y1. As we can easily calculate the number of move the first person had made based on his current location (sum x1 + y1, as he can only move right or down), so, we can also figure out the current location of second person (y2 = x1 + y1 - x2). Keep in mind that, both need to make same number of step to reach the bottom right, so both will have same number of move in any given time.
Lastly, We should notice that, a person cannot visit a location more than one, as the only directions each can take are right or down. Further more, in any state, the number of move each person made are equaled, so, if there exists location(s) visited by both persons, they will visit this location at the same time (and only when x1 = x2), thus, we can easily count the number of coins collected.
From these observations, it can be easily reduced to a similar problem to the problem in OP's link:
Starting from state (x1, x2, y1), as each person can only move right or down, we will have following next states:
(x1 + 1, x2 + 1, y1) : Both move to the right.
(x1 + 1, x2, y1) : First person move right, second move down
(x1, x2 + 1, y1 + 1) : First move down, second move right
(x1, x2, y1 + 1) : Both move down.
So, we have our dynamic programming formula:
dp[x1][x2][y1] = coin[x1][y1] + (x2 != x1 ? coin[x2][y2] : 0 ) + max(dp[x1 + 1][x2 + 1][y1], dp[x1 + 1][x2][y1], dp[x1][x2 + 1][y1 + 1], dp[x1][x2][y1 + 1])
I'm not clear on the exact requirements for the 2 traversals you need but for any given traversal here is what I would suggest. Use Dijkstra's algorithm but build it such that instead of having the determining factor being the length/weight of a connection between 2 nodes make it the values of the grid square. It is also important to make sure it checks for the path with the max value instead of the min value.
Taking this approach should make it so that if there is more than one way to get to a square (which there will be most of the time) the algorithm will ignore all but the path that has accumulated the max value thereby reducing the number of paths that need to be checked.
ex:
Input :
int arr[R][C] = {{3, 6, 8},
{5, 2, 4},
{5, 1, 20},
{5, 1, 20, 10},
};
start:
(0,0) 3
first step:
P1: (0,0) 3 , (1,1) 2 Total = 5
P2: (0,0) 3 , (1,0) 5 Total = 8
both are still in the running for the best path.
Step 2:
both P1 and P2 can have their next step to (2,1) 1 in the brute force method you would have both paths continues through the rest of the graph but in this method we see P2 has a greater value than P1 so there is no need to continue with P1 and from that square onward just continue with P2.

Check if a given sequence of moves for a robot is circular or not

Given a sequence of moves for a robot, check if the sequence is circular or not. A sequence of moves is circular if first and last positions of robot are same. A move can be on of the following.
G - Go one unit
L - Turn left
R - Turn right
Input:path[] = "GLGLGLG"
Output: Given sequence of moves is circular
This question can be solved easily:http://www.geeksforgeeks.org/check-if-a-given-sequence-of-moves-for-a-robot-is-circular-or-not/
My Question is what if we are only given a certain path and the robot can move on to that path infinite times.
Ex:
Input:path[]="GL"
So robot can move on this path 4 times thus a cycle is possible.
Please suggest some approach to check if a cycle is possible or not with the given path.
The result of performing a path from a starting point (x,y) and a starting direction d in {0,1,2,3} is two-fold:
Moving from (x,y) to (x',y')
Changing the direction from d to d'
Case 1: d == d'
There is no direction change. We either move away from the origin or not. In other words: cyclic if and only if (x,y) == (x',y')
Case 2: d == (d' + 2) mod 4
There is 180° direction change. Performing the path a second time will move the exact same vector back from (x',y') to (x,y). Cyclic.
Case 3 (Last): d == (d' + 1) mod 4 or d == (d' + 3) mod 4
There is a 90° direction change (either clockwise or counter-clockwise). Performing the path four times will move the exact same vector around a "rectangle" from (x,y) to (x + dx, y + dy), to (x + dx - dy, y + dy + dx), to (x + dx - dy - dx, y + dy + dx - dy), to (x + dx - dy - dx + dy, y + dy + dx - dy - dx) = (x, y), where dx = x'-x, dy = y'-y. Cyclic.
Thus the algorithm is fairly straight forward:
Simulate path once starting with (x,y) == (0,0) and d = 0
return cyclic iff d' != 0 || (x',y') == (0,0)
You can solve this problem by applying algorithm given in link for given sequence repeated 4 times.
Why?
After each sequence your direction can change:
One to the left/right (in clockwise). Then after next three times
your direction will be same as initial.
Two to the left/right (in clockwise). Then after next sequence your
direction will be same as initial, also after next three.
Zero. Of Course your direction is same as initial, also after next
three.
If after a few sequences your direction is the same as initial it mean the moves you are going to make will be the same as previous and after 4 sequences your direction always will be the same as initial.
Suppose you are not back at origin at the end of your path (that is covered by the original problem).
Now let |L| be the number of left turns and |R| be the number or right turns; and let (x,y) be your position at the end of the path.
switch ( (|L|-|R|) % 4 ) {
case 0: you'll be facing the same direction at the end as you did originally, so you will never get back.
case 1: you'll be facing left at the end, so repeating the path will move you by (-y, x). So you'll get back after 4 repetition of the path while the endpoints of the paths will form a square that you cover in a counter-clockwise order.
case 3: Similar to case 1, just you cover the square in clockwise order.
case 2: you'll be facing backwards, so repeating the path will move you by (-x,-y). "There and back again..."
}
So if all you need is a yes/no answer then just count L's and R's, and look at (|L|-|G|)%4. If that's 0 then you also need to execute the original algorithm to see if you got back to origin.

What is the area covered by a Random walk in a 2D grid?

I am a biologist and applying for a job, for which I need to solve this question. It is an open book test, where the internet and any other resources are fair game. Here's the question - I'm stuck on how to approach it and would appreciate pointers. My intuition is posted underneath.
Background
Your neighbor is a farmer with two cows, Clarabelle and Bernadette. Each cow has its own square pen that is 11m on a side (see first figure). The farmer is heading out of town for a trip and plans to leave the cows in their respective pens, which are completely filled with grass to start. The cows begin in the center of the pen, and will slowly move around the pen eating the grass. They move around the pen very slowly, always pausing to eat or rest after every step. If you divide the pen into 1m squares, the cows can move one square in any direction each step (like a king on a chess board), as shown in the second figure.
After each move, the cow will spend 20 minutes in the new square eating grass, if it is available. Once the grass in a square is eaten, it is gone forever. If the cow moves to a square whose grass was already eaten, then the cow will spend 20 minutes resting in that square. After 20 minutes, whether resting or eating, the cow moves to another square. If a cow is in a square adjacent to the fence, she will never try to move in the direction of the fence. The cows never stay in the same square twice in a row -- they always move to a different one after resting or eating. The first figure shows an example of what a pen might look like after some hours, with the brown spots indicating squares that have been grazed.
The first cow, Clarabelle, has no preference for direction when she moves. She is equally likely to move in any direction at all times. Let p be the probability that she moves in a direction, as shown in the first figure below.
The second cow, Bernadette, prefers to move towards squares with grass. She is twice as likely to move towards a space that has grass as she is towards a space that she has already eaten, as shown in the second figure below.
Questions
If the farmer returns after 48 hours, what percentage of the grass in her pen do you expect Clarabelle to have eaten?
How long do you expect it will take for Bernadette to eat 50% of the grass in her pen?
Suppose that if either of the cows go 24 hours without eating any grass, she will die. Which cow is expected to survive longer?
My intuition
This appears to be modeling a random walk through a 2 dimensional grid. I can for instance figure out the probability of being at a particular node in the grid, after a given time. But I'm not sure how to think about the area covered by the cow as it walks through. Would appreciate any insights.
Edit: The final aim here would be for me to write some sort of a program for this. This isn't a purely mathematics question and thus the post here.
Here is a way of computing the probabilities (for Clarabelle):
Start with a grid of 0, except 1 on the (6, 6) cell, this is your probability grid for time t = 0.
At time t + 1, the probability p(x, y, t + 1) of being on cell (x, y) is given by: p(x, y, t + 1) = p1 * p(x + 1, y, t) + p2 * p(x + 1, y - 1, t) + ... (you have eight term in the sum).
Note that all the pi are not equals: the probability can be 1/3 (corner), 1/5 (edge), or 1/8 (any other cell).
You can dynamically update your grid by running this for each step t = 0 to t = 144 (48h).
If you want to know the probability for a cell already been eaten, it is simply 1 - Pn where Pn if the probability of the cell never been visited, which is:
(1 - p(x, y, 0)) * (1 - p(x, y, 1)) * (1 - p(x, y, 2)) * ...
Here is a code that compute these probability using numpy in Python (basically, this is considering a Markov Chain where the state X is the set of all cells |X| = 121, and the transition matrix T = {Tij} where Tij is the probability of moving from i to j):
GridSize = 11
TranSize = GridSize * GridSize
T_Matrix = np.zeros((TranSize, TranSize), dtype = float)
for u in range(T_Matrix.shape[0]):
for v in range(T_Matrix.shape[1]):
ux, uy = u % GridSize, u // GridSize
vx, vy = v % GridSize, v // GridSize
if u == v or abs(ux - vx) > 1 or abs(uy - vy) > 1:
p = 0
elif (ux == 0 or ux == 10) and (uy == 0 or uy == 10):
p = 1/3
elif ux == 0 or ux == 10 or uy == 10 or uy == 0:
p = 0.2
else:
p = 0.125
T_Matrix[u, v] = p
pxy = np.zeros((TranSize, ), dtype = float)
pxy[11 * 5 + 5] = 1
eat = 1 - pxy
for _ in range(144):
pxy = pxy.dot(T_Matrix)
eat *= (1 - pxy)
print((1 - eat).reshape((GridSize, GridSize)))
The algorithm for Bernadette is a bit more complex because your p1, p2, ... are probabilistic, so you get two terms for each adjacent cell.
Once you have all these probabilities, you can easily find what you want.
There are two ways to approach such problems: analytically or via simulation.
If you'll simulate the process using a Monte-Carlo based method, you can easily find the answers by averaging the results of many trails.
I would assume that this is what you're expected to do, unless you were guided otherwise.

Fast algorithm for testing if every rectangle built using any two points from a list contains a third point from that list

The problem is as it follows:
Given N (N <= 100,000) points by their Cartesian coordinates, test if every rectangle (with an area > 0) built using any two of them contains at least another point from that list either inside the rectangle or on his margin.
I know the algorithm for O(N^2) time complexity. I want to find the solution for O(N * logN). Memory is not a problem.
When I say two points define a rectangle, I mean that those two points are in two of its opposite corners. The sides of the rectangles are parallel to the Cartesian axes.
Here are two examples:
N = 4
Points:
1 1
3 5
2 4
8 8
INCORRECT: (the rectangle (1, 1) - (2, 4) doesn't have any point inside of it or on its margin).
N = 3
Points:
10 9
13 9
10 8
CORRECT.
Sort the points in order of the max of their coordinate pairs, from lowest to highest (O(n*log(n))). Starting with the lower-left point (lowest max coordinate), if the next point in the ordering does not share either the original point's x-value or its y-value (e.g. (1,2) and (5,2) share a y-coordinate of 2, but (1,2) and (2, 1) have neither coordinate in common), the set of points fails the test. Otherwise, move to the next point. If you reach the final point in this way (O(n)), the set is valid. The algorithm overall is O(n*log(n)).
Explanation
Two points that share a coordinate value lie along a line parallel to one of the axes, so there is no rectangle drawn between them (since such a rectangle would have area=0).
For a given point p1, if the next "bigger" point in the ordering, p2, is directly vertical or horizontal from p1 (i.e. it shares a coordinate value), then all points to the upper-right of p2 form rectangles with p1 that include p2, so there are no rectangles in the set that have p1 as the lower-left corner and lack an internal point.
If, however, the next-bigger point is diagonal from p2, then the p1 <-> p2 rectangle has no points from the set inside it, so the set is invalid.
For every point P = (a, b) in the set, search the nearest points of the form Y = (x, b) and X = (a, y) such that x > a and y > b.
Then, find if the rectangle defined by the two points X, Y contains any* internal point R besides P, X and Y. If that is the case, it's easy to see that the rectangle P, R does not contain any other point in the set.
If no point in the set exists matching the restrictions for X or Y, then you have to use (a, ∞) or (∞, b) respectively instead.
The computational cost of the algorithm is O(NlogN):
Looking for X or Y can be done using binary search [O(logN)] over a presorted list [O(NlogN)].
Looking for R can be done using some spatial tree structure as a quadtree or a k-d tree [O(logN)].
*) If X, Y contains more than one internal point, R should be selected as the nearest to P.
Update: the algorithm above works for rectangles defined by its botton-left and upper-right corners. In order to make it work also for rectangles defined by its botton-right and upper-left corners, a new point X' (such that it is the nearest one to P of the form X' = (a, y') where y' < b) and the corresponding rectangle defined by X', Y should also be considered for every point in the set.

How to get the length of a segment crossing a square?

I have a line, defined by the parameters m, h, where
y = m*x + h
This line goes across a grid (i.e. pixels). For each square (a, b) of the grid (ie the square [a, a+1] x [b, b+1]), I want to determine if the given line crosses this square or not, and if so, what is the length of the segment in the square.
Eventually, I would like to be able to do this with multiple lines at once (ie m and h are vectors, matlab-style), but we can focus on the "simple" case for now.
I figured how to determine if the line crosses the square:
Compute the intersection of the line with the vertical lines x = a and x = a + 1, and the horizontal lines y = b and y = b + 1
Check if 2 of these 4 points are on the square boundaries (ie a <= x < a + 1 and b <= y < b + 1)
If two on these points are on the square, the line crosses it. Then, to compute the length, you simply subtract the two points, and use Pythagorean theorem.
My problem is more on the implementation side: how can I implement that nicely (especially when selecting which 2 points to subtract) ?
Let square be defined by corner points (a,b), (a+1,b), (a,b+1), (a+1,b+1).
Step 1: Check if the line intersects the square...
(a)Substitute each of the coordinates of the 4 corner points, in turn into y - mx - h. If the sign of this evaluation includes both positive and negative terms, go to step b. Otherwise, the line does not intersect the square.
(b)Now there are two sub-cases:
(b1)Case 1: In step (a) you had three points for which y - mx - h evaluated to one sign and the fourth point evaluated to the other sign. Let this 4th point be some (x*,y*). Then the points of intersection are (x*,mx*+h) and ((y*-h)/m,y*).
(b2)Case 2: In step (a) you had two points for which y - mx - h evaluate to one sign and the other two points evaluated to the other sign. Pick any two points that evaluated to the same sign, say (x*,y*) and (x*+1, y*). Then the intersection points are (x*, mx* + h) and (x*+1,m(x*+1) + h).
You would have to consider some degenerate cases where the line touches exactly one of the four corner points and the case where the line lies exactly on one side of the square.
Your proposed method may meet with problems in step (1) when m is 0 (when trying to compute the intersection with y = k).
if m is 0, then it's easy (the line segment length is either 1 or 0, depending on whether b <= h <= b+1).
Otherwise, you can find the intersections with x = a and a+1, say, y_a, y_{a+1} via a substitution. Then, clip y_a and y_{a+1} to between b and b+1 (say, y1 and y2, i.e. y1 = min(b+1, max(b, y_a)) and similarly for y2), and use the proportion abs((y1-y2)/m) * sqrt(m^2+1).
This makes use of the fact that the line segment between x=k and x=k+1 is sqrt(m^2+1), and the difference in y is m, and similarity.
You can do like this:
first find center of square and then find length of diagonal. If the distance from center of square to line is less than length of diagonal then the line will intersect the square. and once you know that line will intersect then you can easily find the intersected line segment. I think you are trying to make weight matrix for Algebraic reconstruction technique. I hope this is correct answer. This was my first answer in stack flow. :)

Resources