Counting number of co-ordinates in hypercube - algorithm

In an N-dimensional grid the co-ordinates of a cell are denoted as X1, X2, ..., XN. Any cell with negative co-ordinate are colored white. The origin cell (the one with all zero co-ordinates) is colored as black. The color of a cell in (X1, X2, ..., XN) depends on the N cells with co-ordinates (X1-1, X2, ..., XN), (X1, X2-1, ..., XN), ...., (X1, X2, ..., XN-1). The cell is colored white if and only if the number of black colored cells among these N co-ordinates are even, otherwise the cell is colored black.
Now, given the starting and ending co-ordinate of sub-hypercube. All the co-ordinates will be non negative integers for which the query is done. We've to compute how many hyper cells in this sub hypercube are colored black?
Please suggest me hint, reference or anything which could help me to solve it.

This rule results in a well known fractal - The Sierpinski triangle
Here is an image of it in 2D:

A brute force algorithm:
fill the hypercube (the needed part) with value 'unknown'.
color[00000] = 1 #black
sum = 0
for each cell in sub-hypercube:
sum += getcolor(cell)
return sum
getcolor(cell):
if color[cell] == unknown
c = 0 #white
for each neighbour cell in decreasing direction within non-negative boundary:
c = c xor getcolor(neighbour)
color[cell] = c
return color[cell]

Related

How do you find the coordinates of a matrix in a rotate matrix?

I'm looking for a function that takes the arguments: (x, y, m, n, rot) where rot%90 always equals 0.
And outputs equivalent coordinates x, y from a matrix of dimensions m, n in the same matrix rotated by rot degrees.
For example, given (x=0, y=0, m=3, n=3, rot=90) it would output [2, 0].
In other words - the top left would move to the top right.
I tried using matrix rotations but these aren't of use here since I'm rotating around the center of an array - at the very least they'd need some manipulation.

How to distinguish internal and external face of polygon

So I have a set of points making up a simple polygon
points = [(x0, y0), (x1, y1), ..., (xn, yn)]
The polygon may be concave or convex, both cases must be handled.
Next I create two arcs for each line by treating the arc between point A-B as different from the arc between point B-A. Next I create paths from these points by always choosing the closest counter-clockwise arc. So one path goes clockwise and one counter-clockwise: [(x0, y0), (x1, y1), ... , (xn, yn)] and [(xn, yn), (xn-1, yn-1), ... , (x0, y0)]
By traversing these arcs how do I know if the arcs are creating an internal face or an external face?
For example, in the two polygons below the same orange line is used on two different polygons. In the first polygon the top orange arc is in the internal face (pointing inwards) while in the other polygon the top orange arc is in the external face (pointing outwards).
My question arose from the answer by #HEKTO in this post: How to find all the polygonal shapes of given the vertices?.
Use Green's theorem. Iterate over the points and compute the integral, then check the sign. Like this:
decimal sum = 0.0;
for(int current = 0; current < points.length; current++)
{
int next = current + 1;
if (next == points.length)
next = 0;
sum += (points[this].y + point[next].y) * (point[next].x - point[this].x);
}
Check the sign of sum to find out whether the winding is clockwise or counter-clockwise. Which is which will depend on which direction the Y axis increases in.
Note that if you were trying to compute the area of the polygon you would multiply the Y part of the equation by 0.5, but since you're only interested in the sign of the result you don't need to.

Perimeter around a 2D grid-shape

Given a 2D grid of square cells of the form grid[x,y], I would like an algorithm that produces an ordered set of points that form the perimeter of the shape. In other words, the algorithm would produce a perimeter route around the corners of the shape as shown in this image:
.
I have looked at posts like this (where I got the above image), and I can find the corners of the shape. I have two questions: 1) once I have found the corners of the shape, how would I iterate over them in order to find a correct (and valid) route? 2) Would such a method to find the route consistently produce clockwise/counterclockwise routes? It does not matter to me that order of the vertices is clockwise/counterclockwise, only that they are consistently either clockwise or counterclockwise.
Thanks for any help
This assumes that any single corner won't be visited more than once per circuit. in other words, no corners where there are two grey and two black with the two grey squares in non adjacent corners.
Get your corners in some data structures that let you quickly :
get a list of all corners with a given x coordinate ordered by y coordinate.
get a list of all corners with a given y coordinate ordered by x coordinate.
Here's the algorithm:
Start with arbitrary corner c.
We'll say it has 3 adjacent black squares and 1 grey, and that the
1 grey square is in the -x,+y direction.
Choose perimeter direction. We'll say clockwise.
Determine which direction the perimeter goes in that corner. This can be done
by looking at the direction of the adjacent tile there's only 1 color of.
In our example, the perimeter goes -x/+y
Determine if c is concave or convex.
Convex has 3 adjacent black squares, concave has 3 adjacent grey squares.
In our example, c is convex because it has 3 adjacent black squares.
Knowing the direction of the perimeter from that corner and if it's concave or
not tells us what direction is clockwise:
clockwise at convex +x/-y is +x,
clockwise at convex +x/+y is +y,
clockwise at convex -x/-y is -y,
clockwise at convex -x/+y is -x
If it is concave clockwise goes the other direction.
(obviously if the desired perimeter direction is counterclockwise, it's the opposite)
Because c in our example is a convex corner and it goes -x/+y,
that means clockwise is along the x wall, so set current_axis = x,
It goes negative in that direction so set current_direction = -1
Otherwise, it would be set to 1
create list ordered_corner_list that only contains c
While length of ordered_corner_list < number of corners:
Get list of all corners with same value of current_axis as c ordered by the other axis.
e.g. for the first iteration, get same x value as c ordered by y
if current_direction = -1:
find node with the next lowest ordered value from c.
e.g. for the first iter, get corner with next lowest x from c
else:
find node with the next highest ordered value from c
assign that node to c
append c to ordered_corner_list
set current_axis = the other axis
e.g. for the first iteration, current_axis = y here
set current_direction to the direction that corner goes in the current_axis

how do I determine a cross shape with given vertices

I am having trouble forming an algorithm to determine if 12 vertices that was inputted by a user in any order, will form a cross shape in a 2D plane.
From the way I looked at it, it can be two rectangle intersecting.
Should I choose to brute force it by comparing the distances,
I will end up having 67 distances from the 12 vertices, which to compare all of them would not be feasible.
Is there any characteristic of a cross or shape that I could use?
What you want is a cross shape define by two intersecting rectilinear rectangles with protrusions greater than zero on all four sides. I believe the following algorithm will fully determine that for you.
Insure that none of the 12 points is identical.
There should only be 4 distinct X values among the 12 points. Put them in ascending order into an array that we’ll call your X-vector.
Do the same with Y values creating a Y-vector with 4 distinct values.
Make a 4x4 array, initializing all cells to zero.
Go through each of the 12 values using their X and Y values along with the X-vector and Y-vector to select a cell in the 4x4 array to increment. Thus if you had a point (12,9) and 12 was at the [0] entry of the X-vector and 9 was in the [2]entry of the Y-vector, you would increment the [0,2] cell of the 4x4 array.
Now your 4x4 Array should look exactly like this:
0, 1, 1, 0
1, 1, 1, 1
1, 1, 1, 1
0, 1, 1, 0
If so, then it is a cross as you have defined it. And if not, or if it fails at any previous step, the it is not a cross.
Something like the following should work:
collect the points in a set or list
iterate the points and find the distinct X and Y coordinates; there should be exactly four different values for X and Y, respectively; if there are more or fewer, it's not a cross-shape
sort the distinct X and Y coordinates and call them x1 through x4 and y1 through y4
check whether the original list of points contains exactly the points (x1, y2), (x1, y3), (x2, y1), (x2, y2), (x2, y3), (x2, y4), (x3, y1), (x3, y2), (x3, y3), (x3, y4), (x4, y2), and (x4, y3), in any order
if there are other properties to be met, e.g. the four arms having same lengths, check those, too, using the identified distinct X and Y values

How many integer points within the three points forming a triangle?

Actually this is a classic problem as SO user Victor put it (in another SO question regarding which tasks to ask during an interview).
I couldn't do it in an hour (sigh) so what is the algorithm that calculates the number of integer points within a triangle?
EDIT: Assume that the vertices are at integer coordinates. (otherwise it becomes a problem of finding all points within the triangle and then subtracting all the floating points to be left with only the integer points; a less elegant problem).
Assuming the vertices are at integer coordinates, you can get the answer by constructing a rectangle around the triangle as explained in Kyle Schultz's An Investigation of Pick's Theorem.
For a j x k rectangle, the number of interior points is
I = (j – 1)(k – 1).
For the 5 x 3 rectangle below, there are 8 interior points.
(source: uga.edu)
For triangles with a vertical leg (j) and a horizontal leg (k) the number of interior points is given by
I = ((j – 1)(k – 1) - h) / 2
where h is the number of points interior to the rectangle that are coincident to the hypotenuse of the triangles (not the length).
(source: uga.edu)
For triangles with a vertical side or a horizontal side, the number of interior points (I) is given by
(source: uga.edu)
where j, k, h1, h2, and b are marked in the following diagram
(source: uga.edu)
Finally, the case of triangles with no vertical or horizontal sides can be split into two sub-cases, one where the area surrounding the triangle forms three triangles, and one where the surrounding area forms three triangles and a rectangle (see the diagrams below).
The number of interior points (I) in the first sub-case is given by
(source: uga.edu)
where all the variables are marked in the following diagram
(source: uga.edu)
The number of interior points (I) in the second sub-case is given by
(source: uga.edu)
where all the variables are marked in the following diagram
(source: uga.edu)
Pick's theorem (http://en.wikipedia.org/wiki/Pick%27s_theorem) states that the surface of a simple polygon placed on integer points is given by:
A = i + b/2 - 1
Here A is the surface of the triangle, i is the number of interior points and b is the number of boundary points. The number of boundary points b can be calculated easily by summing the greatest common divisor of the slopes of each line:
b = gcd(abs(p0x - p1x), abs(p0y - p1y))
+ gcd(abs(p1x - p2x), abs(p1y - p2y))
+ gcd(abs(p2x - p0x), abs(p2y - p0y))
The surface can also be calculated. For a formula which calculates the surface see https://stackoverflow.com/a/14382692/2491535 . Combining these known values i can be calculated by:
i = A + 1 - b/2
My knee-jerk reaction would be to brute-force it:
Find the maximum and minimum extent of the triangle in the x and y directions.
Loop over all combinations of integer points within those extents.
For each set of points, use one of the standard tests (Same side or Barycentric techniques, for example) to see if the point lies within the triangle. Since this sort of computation is a component of algorithms for detecting intersections between rays/line segments and triangles, you can also check this link for more info.
This is called the "Point in the Triangle" test.
Here is an article with several solutions to this problem: Point in the Triangle Test.
A common way to check if a point is in a triangle is to find the vectors connecting the point to each of the triangle's three vertices and sum the angles between those vectors. If the sum of the angles is 2*pi (360-degrees) then the point is inside the triangle, otherwise it is not.
Ok I will propose one algorithm, it won't be brilliant, but it will work.
First, we will need a point in triangle test. I propose to use the "Barycentric Technique" as explained in this excellent post:
http://www.blackpawn.com/texts/pointinpoly/default.html
Now to the algorithm:
let (x1,y1) (x2,y2) (x3,y3) be the triangle vertices
let ymin = floor(min(y1,y2,y3)) ymax = ceiling(max(y1,y2,y3)) xmin = floor(min(x1,x2,x3)) ymax = ceiling(max(x1,x2,3))
iterating from xmin to xmax and ymin to ymax you can enumerate all the integer points in the rectangular region that contains the triangle
using the point in triangle test you can test for each point in the enumeration to see if it's on the triangle.
It's simple, I think it can be programmed in less than half hour.
I only have half an answer for a non-brute-force method. If the vertices were integer, you could reduce it to figuring out how to find how many integer points the edges intersect. With that number and the area of the triangle (Heron's formula), you can use Pick's theorem to find the number of interior integer points.
Edit: for the other half, finding the integer points that intersect the edge, I suspect that it's the greatest common denominator between the x and y difference between the points minus one, or if the distance minus one if one of the x or y differences is zero.
Here's another method, not necessarily the best, but sure to impress any interviewer.
First, call the point with the lowest X co-ord 'L', the point with the highest X co-ord 'R', and the remaining point 'M' (Left, Right, and Middle).
Then, set up two instances of Bresenham's line algorithm. Parameterize one instance to draw from L to R, and the second to draw from L to M. Run the algorithms simultaneously for X = X[L] to X[M]. But instead of drawing any lines or turning on any pixels, count the pixels between the lines.
After stepping from X[L] to X[M], change the parameters of the second Bresenham to draw from M to R, then continue to run the algorithms simultaneously for X = X[M] to X[R].
This is very similar to the solution proposed by Erwin Smout 7 hours ago, but using Bresenham instead of a line-slope formula.
I think that in order to count the columns of pixels, you will need to determine whether M lies above or below the line LR, and of course special cases will arise when two points have the same X or Y co-ordinate. But by the time this comes up, your interviewer will be suitably awed and you can move on to the next question.
Quick n'dirty pseudocode:
-- Declare triangle
p1 2DPoint = (x1, y1);
p2 2DPoint = (x2, y2);
p3 2DPoint = (x3, y3);
triangle [2DPoint] := [p1, p2, p3];
-- Bounding box
xmin float = min(triangle[][0]);
xmax float = max(triangle[][0]);
ymin float = min(triangle[][1]);
ymax float = max(triangle[][1]);
result [[float]];
-- Points in bounding box might be inside the triangle
for x in xmin .. xmax {
for y in ymin .. ymax {
if a line starting in (x, y) and going in any direction crosses one, and only one, of the lines between the points in the triangle, or hits exactly one of the corners of the triangle {
result[result.count] = (x, y);
}
}
}
I have this idea -
Let A(x1, y1), B(x2, y2) and C(x3, y3) be the vertices of the triangle. Let 'count' be the number of integer points forming the triangle.
If we need the points on the triangle edges then using Euclidean Distance formula http://en.wikipedia.org/wiki/Euclidean_distance, the length of all three sides can be ascertained.
The sum of length of all three sides - 3, would give that count.
To find the number of points inside the triangle we need to use a triangle fill algorithm and instead of doing the actual rendering i.e. executing drawpixel(x,y), just go through the loops and keep updating the count as we loop though.
A triangle fill algorithm from
Fundamentals of Computer Graphics by
Peter Shirley,Michael Ashikhmin
should help. Its referred here http://www.gidforums.com/t-20838.html
cheers
I'd go like this :
Take the uppermost point of the triangle (the one with the highest Y coordinate). There are two "slopes" starting at that point. It's not the general solution, but for easy visualisation, think of one of both "going to the left" (decreasing x coordinates) and the other one "going to the right".
From those two slopes and any given Y coordinate less than the highest point, you should be able to compute the number of integer points that appear within the bounds set by the slopes. Iterating over decreasing Y coordinates, add all those number of points together.
Stop when your decreasing Y coordinates reach the second-highest point of the triangle.
You have now counted all points "above the second-highest point", and you are now left with the problem of "counting all the points within some (much smaller !!!) triangle, of which you know that its upper side parallels the X-axis.
Repeat the same procedure, but now with taking the "leftmost point" instead of the "uppermost", and with proceedding "by increasing x", instead of by "decreasing y".
After that, you are left with the problem of counting all the integer points within a, once again much smaller, triangle, of which you know that its upper side parallels the X-axis, and its left side parallels the Y-axis.
Keep repeating (recurring), until you count no points in the triangle you're left with.
(Have I now made your homework for you ?)
(wierd) pseudo-code for a bit-better-than-brute-force (it should have O(n))
i hope you understand what i mean
n=0
p1,p2,p3 = order points by xcoordinate(p1,p2,p3)
for int i between p1.x and p2.x do
a = (intersection point of the line p1-p2 and the line with x==i).y
b = (intersection point of the line p1-p3 and the line with x==i).y
n += number of integers between floats (a, b)
end
for i between p2.x+1 and p3.x do
a = (intersection point of the line p2-p3 and the line with x==i).y
b = (intersection point of the line p1-p3 and the line with x==i).y
n += number of integers between floats (a, b)
end
this algorithm is rather easy to extend for vertices of type float (only needs some round at the "for i.." part, with a special case for p2.x being integer (there, rounded down=rounded up))
and there are some opportunities for optimization in a real implementation
Here is a Python implementation of #Prabhala's solution:
from collections import namedtuple
from fractions import gcd
def get_points(vertices):
Point = namedtuple('Point', 'x,y')
vertices = [Point(x, y) for x, y in vertices]
a, b, c = vertices
triangle_area = abs((a.x - b.x) * (a.y + b.y) + (b.x - c.x) * (b.y + c.y) + (c.x - a.x) * (c.y + a.y))
triangle_area /= 2
triangle_area += 1
interior = abs(gcd(a.x - b.x, a.y - b.y)) + abs(gcd(b.x - c.x, b.y - c.y)) + abs(gcd(c.x - a.x, c.y - a.y))
interior /= 2
return triangle_area - interior
Usage:
print(get_points([(-1, -1), (1, 0), (0, 1)])) # 1
print(get_points([[2, 3], [6, 9], [10, 160]])) # 289
I found a quite useful link which clearly explains the solution to this problem. I am weak in coordinate geometry so I used this solution and coded it in Java which works (at least for the test cases I tried..)
Link
public int points(int[][] vertices){
int interiorPoints = 0;
double triangleArea = 0;
int x1 = vertices[0][0], x2 = vertices[1][0], x3 = vertices[2][0];
int y1 = vertices[0][1], y2 = vertices[1][1], y3 = vertices[2][1];
triangleArea = Math.abs(((x1-x2)*(y1+y2))
+ ((x2-x3)*(y2+y3))
+ ((x3-x1)*(y3+y1)));
triangleArea /=2;
triangleArea++;
interiorPoints = Math.abs(gcd(x1-x2,y1-y2))
+ Math.abs(gcd(x2-x3, y2-y3))
+ Math.abs(gcd(x3-x1, y3-y1));
interiorPoints /=2;
return (int)(triangleArea - interiorPoints);
}

Resources