Supose I have a grid like this one(I don't know the size of the grid)
(-1,1) (0,1) (1,1)
(-1,0) (0,0) (1,0)
(-1,-1) (0,-1) (1,-1)
In this grid are N boxes. I want to write some predicates in order to move the robot in every cell of the grid and check if there is a box or not. It is important not to miss a cell because I don't know where the boxes are.
First of all I have this predicate
init([N,0,0])
N - number of boxex to discover
0,0 - my initial position
The predicates that handle the moves of the robot have got this structure
perform(+ProgramData, +ContainsBox, -Action, -ProgramDataUpdated)
perform([N,X,Y], false, move(west), [N,NX,Y]):- NX is X - 1, !
perform([N,X,Y],false, move(east), [N,NX,Y]):- NX is X + 1, !
perform([N,X,Y], false, move(north), [N,X,NY]):- NY is Y + 1, !
perform([N,X,Y], false, move(south), [N,X,NY]):- NY is Y - 1, !
If a box is in a cell I have this predicate:
discovered([N,X,Y],true,discovered,[NN,X,Y]):-NN is N-1,!.
If I have discovered N boxes my program ends and I have this predicate:
done([0,_,_],_,done,[0,_,_]).
I don't know how to make sure that I don't miss any cell of the grid
Related
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.
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.
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.
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. :)
I have a triangulated isometric grid, like this:
(source: mathforum.org)
In my code, triangles are grouped by columns.
As I hover the mouse, I want to calculate what triangle the mouse coordinates are in. Is there a simple algorithm to do that?
What you want to do is turn this into a grid as much as possible because grids are far easier to work with.
The first thing you do is work out what column it's in. You say you store that so it should be easier by doing a simple integer division on the x coordinate by the column width offset by the box start. Easy.
After that you want to work out what triangle it's in (obviously). How you partially turn this into a grid is you pretend that you have a stack of right angle triangles instead of a stack of isometric triangles.
The triangles have a length along the y axis (the side of the column). Divide that number in two and work out how many steps down you are. Based on the number of steps down and if the column is even or odd will tell you if you're looking at:
+--------+
|-_ |
| -_ |
| -_ |
| -_|
+--------+
or the reverse. At this point you only need to determine which side of the line it's on to determine which right triangle it's in, which also tells you which isometric triangle it's in.
You have a couple of options for this.
You could use something like Bresenham's line algorithm to rasterize the hypotenuse and when you hit the column you're in work out if you're above or below that line;
Because you only have two possible grids here (one being the reverse of the other so it's really only one). You could store a array of row values, saying that for column 3, the hypotenuse is at offset 2, whereas for 6 it's at 4 and so on.
You could even use (1) to generate (2) as a fast lookup.
The only other thing to consider is what happens if the mouse cursor is on an edge?
This is similar to what cletus said, but a different way to look at it I suppose.
I am assuming the triangle side is 1.
Suppose you have the grid as below:
y'
/
/__/__/__/__/__/__/
/__/__/__/__/__/__/
/__/__/__/__/__/__/____ x'
(0,0)
If you consider the grid in a co-ordinate system in which the x & y axes are at an angle of 60 degrees, a point whose co-ordinate in the angled system (x',y') will correspond to the coordinate in the orthogonal system (with same origin an general direction of axes) to (x,y).
In your problem, you are given (x,y), we need to find (x',y') and then figure out the triangle.
If i is the unit vector along x and j the orthogonal along y, then we have that
x'* i + y'( i/2 + sqrt(3) * j /2) = xi + yj.
(Basically the unit vector along the 'angled' y axis is i/2 + sqrt(3)/2 * j. The unit vector along the x axis is the same as the normal x-axis, i.e. i).
Thus
x' + y'/2 = x
y' * sqrt(3)/2 = y
Solving gives:
y' = 2*y/sqrt(3)
x' = x - y/sqrt(3)
Assume for now that x' and y' are positive.
Now if c = [x'], the integer part of x'
and r = [y'], the integer part of y'
then in the (angular) grid, the point lies in the cth column and the rth row. (Counting right and up and start counting at 0).
Thus we have narrowed down your point to a parallelogram
____
/\ * /
/___\/
(c,r)
Now in order to find out which triangle it is in you can consider the fractional parts of x' and y'.
{x} = x' - [x'] = x' - c.
{y} = y' - [y'] = y' - r.
Now,
if {x} + {y} > 1, then the point lies in the triangle marked with *.
if {x} + {y} < 1, then the point lies in the other triangle.
if {x} + {y} = 1, then the point lies on the line common to the two triangles.
Hope that helps too.